🔍 搜尋結果:登入

🔍 搜尋結果:登入

Github Desktop 新手入門教學:第7課 ── 能夠從 Github 抓專案下來

## 課程目標 - 能夠從 Github 抓專案下來 ## 課程內容 我們在上一課發佈專案到 Github 了 這次來學習把專案從 Github 抓下來吧! 首先來把電腦上的專案刪掉,模擬我們今天拿到一台新電腦的情境 在主視窗點選 `Current Repository` 會秀出專案列表 對著我們的專案 `my-first-repo` 按右鍵,然後選 `Remove` 刪除,確認視窗繼續按 `Remove` 會發現 Github Desktop 變回初始畫面了! --- 但目前只是 Github Desktop 停止追蹤專案而已,那個資料夾其實還在電腦上喔 請在電腦上,直接前往那個資料夾,會發現檔案都還在 請把 `my-first-repo` 整個資料夾刪掉,這樣才是真的模擬拿到新電腦 --- 現在來試著把專案從 github 抓下來吧! 點擊 `Clone a Repository from the Internet` 因為已經登入 github 了,應該會顯示專案列表 找到上次發佈的 `my-first-repo` 專案 (如果專案沒出現,畫面上有一個重新整理的按鈕,按一下) 然後 `Clone` 按鈕按下去 成功囉!專案回來囉! `History` 分頁按下去,看看是不是跟之前都一模一樣? 軟體工程師在跨裝置工作(使用多台電腦)、或是多位工程師合作時,就是這樣同步專案內容的! ## 課後作業 接續前一課的作業,專案已經傳到 github 了 現在來模擬你拿到新電腦,第一次從 github 抓專案的情境 請把原本電腦上的那個專案資料夾,整個刪掉 這時去看 Github Desktop,應該會顯示「Can't find」開頭的提示 請將 Github Desktop 視窗截圖,這是本次作業的第一張截圖 截圖完畢之後,點擊畫面上的 `Remove` 將這個專案刪掉 --- 現在電腦上已經沒有專案了,就當作你今天拿到一台新電腦,準備開始工作,要把 github 上的專案抓下來 請點擊 `Add` 然後選 `Clone Repository...` 接著找到你在 github 上的專案 把剛剛那個專案整個抓下來之後,你應該會發現,剛剛整個刪掉的專案資料夾,現在內容又通通出現囉! 請將 Github Desktop 視窗截圖,這是本次作業的第二張截圖 --- 完成以上任務,你就完成這次的課程目標了! --- 交作業的方法: 請把第一張、第二張截圖,分別貼到留言區

Github Desktop 新手入門教學:第1課 ── 學會專案初始化

## 課程目標 - 學會專案初始化 ## 課程內容 在開始之前,我先再次說明一下 Git 與 Github Desktop 的不同 Git 是軟體工程師每天都會用到的,強大的專案版本管理工具,本身是命令列工具,要一直在終端機打指令 Github Desktop 是 Github 公司,為了方便入門者,所開發的 GUI(圖形化介面)工具,用起來簡單很多 本課程會交替使用這兩個名詞,前者代表 Git 正在發揮作用,後者代表正在操作 Github Desktop 功能 有點分不清楚沒關係,反正就知道有這差別即可,日後經驗更多,會越來越清楚 --- 讓我們開始玩玩看 Github Desktop 吧! 請先前往官網下載並安裝 https://desktop.github.com/ 在登入 Github 帳號的步驟,先選 `Skip this step` 跳過就好,我們後面課程再登入就好 --- 進入到 Github Desktop 主畫面之後,首先我們要設定一下 git 基本資訊 也就是在用 git 管理專案紀錄時,每次提交變化時,當筆提交的「作者資訊」 請在 Github Desktop 上方的導覽列,選擇 `Preferences` 然後選擇 `Git` 把 `Name` 跟 `Email` 欄位填寫一下,然後點擊 `Save` 按鈕,就可以囉! --- 來建立第一個用 git 管理的專案吧! 在主畫面,點選 `Create a New Repository on your Hard Drive` `Name` 就輸入 `my-first-repo` `Description` 可以省略不填 `Local Path` 隨便選一個方便的路徑 其餘的選項都保持預設就好,不用勾選 `Create Repository` 點下去,就建立第一個專案資料夾囉! --- 請在電腦上,直接打開那個資料夾,然後在資料夾裡面新增一個檔案 `my-document-1.txt`,裡面放入以下內容 ``` 我的第一個筆記檔案 ``` 接著打開 Github Desktop 看看狀況 會看到 `Changes` 分頁下面,有出現 `my-document-1.txt` 這個檔案 然後右側的主視窗,有顯示出檔案內容 這代表 git 已經發現它的存在了 我們成功使用 git 開始追蹤專案的歷史變化了! 這是一個很好的開始,本課先做到這樣就好! ## 課後作業 假設你正在準備履歷表,整理一些自我介紹、經營個人品牌的檔案 請建立一個名為 `my-resume` 的資料夾,並使用 git 開始追蹤這個資料夾 請在其中建立一個 `me.txt` 的文字檔案,裡面放入以下內容 ``` # 我是誰 - 我是XXX,目前在自學程式設計 # 我的學歷 - 高中:積極高中 - 大學:品質大學 ``` 你應該會在 `Changes` 分頁看到檔案出現 然後在右側主視窗,看到文字檔案的內容 完成以上任務,你就完成這次的課程目標了! --- 交作業的方法: 請直接截圖 Github Desktop 視窗的內容,上傳到留言區

【前端動手玩創意】動態生成的藝術|小心,亂改DOM你可能會被打臉。

## 目錄 ##### [【前端動手玩創意】等待的轉圈圈效果 (1)](https://ithelp.ithome.com.tw/articles/10311621) ##### [【前端動手玩創意】google五星評分的星星(2)](https://ithelp.ithome.com.tw/articles/10311643) ##### [【前端動手玩創意】CSS-3D卡片翻轉效果(3) (今天難度頗高,想挑戰再進來!)](https://ithelp.ithome.com.tw/articles/10311672) ##### [【前端動手玩創意】一句CSS做出好看的hero section!(4)](https://ithelp.ithome.com.tw/articles/10311691) ##### [【前端動手玩創意】創造一個Skill bar(5)](https://ithelp.ithome.com.tw/articles/10311756) ##### [【前端動手玩創意】遮蔽廣告(D卡未登入)腳本、自定義新增名單(6)](https://ithelp.ithome.com.tw/articles/10311999) ##### [【前端動手玩創意】前端canvas截圖的招式!竟然有三招,可存成SVG或PNG (7)](https://ithelp.ithome.com.tw/articles/10312001) ##### [【前端動手玩創意】讓你的PDF檔案更難被抓取(8)](https://ithelp.ithome.com.tw/articles/10312046) ##### [【前端動手玩創意】哇操!你敢信?花式寫todo-list,body裡面一行都沒有也能搞?(9)](https://ithelp.ithome.com.tw/articles/10312056) ##### [【前端動手玩創意】卡片製作,才不是!是卡片製作器!(10)](https://ithelp.ithome.com.tw/articles/10312066) ##### [【前端動手玩創意】太屌了吧!?用Class(類)製作Jquery的效果!(11)](https://ithelp.ithome.com.tw/articles/10312114) ##### [ 【前端動手玩創意】置頂按鈕,老梗經典|帶你的網頁搭電梯(12)](https://ithelp.ithome.com.tw/articles/10312922) ## 前情提要 一陣子沒寫前端動手玩創意了 今天要來點好料的 我們談談關於藝術 對 就算是寫程式我們也是可以有藝術氣息的 別這麼驚訝XD 假設我有一組資料 一般人來說 最直覺的就是把html裡面的元素寫出來寫死 直覺菜鳥就是寫出來啊 ``` <div id="items_list"> <li class="buy_item">1.紅茶 <div class="price">10</div> <div class="del_btn">X</div> </li> <li class="buy_item">2.奶茶 <div class="price">15</div> <div class="del_btn">X </div> </li> <li class="buy_item">3.綠茶 <div class="price">30</div> <div class="del_btn">X</div> </li> </div> ``` 要更新則是就去更改DOM就好了 反正我都學會JS了 有什麼大不了(? 但是現在已經進入大前端時代了就算你寫原生 也會有data model的概念 這部分可以參考站長阿川寫過的好文 裡面的文筆跟邏輯 不誇張 是我見過「華文圈寫得最好的前端教學」 尤其就是這篇 關於data model的介紹 切入點非常的有趣也很有道理 有興趣的自己去花心思讀看看 [認識 data model 與 render function](https://codelove.tw/@howtomakeaturn/post/9xLo5q) 稍微有點料的前端學習者 本身就會寫一寫 想說:既然有一隻API是createElement 那是不是我可以整個html都用js寫出來(? 這是個超級有趣的觀點 ## 關於data render的概念: 「是不是我可以整個html都用js寫出來」 相傳牛頓提出三大定律以後 認為地球和八大行星一開始的慣性力叫「上帝的第一推動力」 實際上這個: 「整個html都用js寫出來」 也是推動前端往框架邁進的思考第一步 可以說是前端慣性的上帝推力了 當然如果你有打籃球 也可以比喻成上籃的第零步XD ## 觀念筆記 ### html程式碼 ``` <div id="buylist"> <h1>myBuylist 購物清單</h1> <div class="buyitem"> <label>產品名</label> <input/> <label>價錢</label> <input/><span class="addbtn">+新增</span> </div> <div id="items_list">這邊準備用JS插入東西所以這段只是說明文字</div> </div> ``` 把整個頁面的元素寫出來 但是資料的區塊保留著 因為等等我們要用JS的API去動態生成 未來直接data render 方便更新與管理 ### JS程式碼 ``` var shoplist = {}; shoplist.name = "購物清單"; shoplist.list = [ { name: "吹風機", price: "300" }, { name: "麥克筆", price: "20" }, { name: "筆記型電腦", price: "29300" }, { name: "Iphone 9", price: "5200" }, { name: "神奇海螺", price: "1000" }, ]; var item_html = "<li id={{id}} class='buy_item'>{{name}}<div class='price'>{{price}}</div><div class='del_btn'>X</div></li>"; var total_html = "<li class='buy_item total'>總價<div class='price'>{{price}}</div><div class='del_btn'>X</div></li>"; var total_price = 0; for (var i=0; i < shoplist.list.length; i++) { var item = shoplist.list[i]; total_price += item.price; var current_item_html = item_html.replace("{{num}}", i + 1) .replace("{{name}}", item.name) .replace("{{id}}", "buyitem_" + i) .replace("{{price}}", item.price); $("#items_list").append(current_item_html); } ``` 這邊值得關注的一點是資料的處理 也就是數據結構上使用物件與陣列去儲存資料 為什麼要學 陣列 為什麼要學物件 這兩個都是抽象的名詞 他們都是為了來處理資料所規劃的兩種不同內容 ## 關於物件與陣列 物件就像是RPG角色 會有很多的屬性 魔法 敏捷 力量 血量 這些屬性都是被附加在person上面 所以person.blood是一個資料 person.power是一個資料 person.magic是一個資料 最後都存在person裡面 這個person就是一個含有很多屬性的物件 感覺就是有血有肉很3D 而陣列就比較平面化 就是很多數字排成一列而已 其實沒什麼特別需要關注的 這兩個也不會不好區分 只要稍微做個比喻 都很好理解 以我們的code來講解 shoplist就是一個物件 含有一些屬性 包含名字與清單 因為清單很多 所以清單用一個陣列儲存 陣列裡面放很多個物件 這些物件就是每一個清單包含的那些購買項目 其實不用太在意誰是誰因為用看的就很清楚 最後我們用迴圈去把shoplist裡面的每一筆資料都丟進去 中途replace是文字處理 把我們設置的{{name}}這種花括號的東西換成真實資料 這部分有點樣板語言的感覺XD 其實非常有趣 很值得玩味 ## 心得 這次比較多實在的JS程式碼 就不只是玩玩切版了 算是有點靠近框架的部分(◉3◉) 動手玩創意這個系列其實靈魂之處就在於「有趣」兩個字 坊間把前端描繪成為了找工作的銅臭味 以及把切版講成無聊的工匠苦力活 我認為都是錯誤的解讀 我認為 只要是有趣的地方就是前端最有價值的地方 而不是誰學了那個框架 誰又認為哪個東西比較厲害 哪個語言比較屌 那都是很無聊的文字遊戲罷了 如果你喜歡這樣子的前端 請跟著這個系列繼續走(→ܫ←) 我們才只是在桃花源外的小溪旁玩水而已呢! 未來會往天空飛翔哦XD

分享職場小菜雞所遇到的狀況

感謝站長關懷~ 是的,這禮拜確實有遇到一些之前有稍微碰過卻不太熟悉的東西,也有之前沒有碰過的東西,是有些小崩潰...,但還是可以稍微跟大家分享與請教一下: 這裡有一些前期提要:公司目前的前端開發並不使用現在的主流前端框架,也沒有使用打包整合工具...(像是Webpack、Parcel這類的),JS使用JQuery,並且將JS檔案一個一個的引入網頁中。 ## 遇到的問題1 :CSS樣式問題 過去在自學的時候其開發方法是:在本機開發,然後在處理樣式與RWD時就是開啟Chrome 的 Dev Tools來做調整,但也有遇過在Chrome的Dev Tools中看起來將樣式都調整好了之後,部署到網路上之後換手機來查看頁面時卻發生了一些差異,這些差異可能包含滿版、間距等等,這部分我自己理解的差異可能會是有些手機會有瀏海的緣故以及Chrome與Safari之間的小差異.到新公司後發現在更多的裝置上,例如安卓手機,則存在的差異更多,包含顏色、日期時間選取器等等的樣式,因為型號真的太多了. ###到這裡可以跟大家分享的以及向各位請教的: 這裡我自己有想到幾個解決的方式,第一個是最懶的方法我最想用但是我有些不知道該如何整合給其他人使用的方法,例如透過Vue cli直接在npm下載PostCSS以及Autoprefixer這樣的工具來使用,一次解決主流瀏覽器的差異,但目前我不太曉得如何在公司的開發方法下,不透過整合工具來完成這個流程. 另一個我想到的方法是加入CSS Normalize來減少各個瀏覽器在不同樣式的預設值差異,過去我們可能都有寫過非常簡易CSS reset 例如: ```css= *{ padding: 0; margin:0; box-sizing:border-box; } ``` 但這樣如果把每一個樣式的預設值全部強制歸零,可能會導致有些樣式到後來要重新寫,或許Normalize可以只是單純地減少差異(也是因為網路上有人已經整理好了XD). ## 遇到的問題2 :API串接 過去我自己練習串接API的方式實在是相當簡易,我拿的是中央氣象局開放資料平台的API,所以之前很簡單的一行fetch就拿到資料了,毫無難度哈哈哈,但第一天公司需要我去切幾個版面並且串接運輸資料TDX的資料,恩...我一開始不知道要如何在JS中塞入登入資料並且拿回Token的方式.以及我要查詢的數值該如何發出. ###到這裡可以跟大家分享的以及向各位請教的: 這中間我摸索了fetch的一些選項設定,這應該也適用其他的非同步請求方法,例如ajax、axios(這兩個我還沒用過,後續應該會來摸索一下axios),包含請求方法(method),header與body中的內容設定等等. 至於API該如何塞入a頁面填入查詢參數並且跳轉到b頁面顯示查詢解果,在沒有前端框架全域狀態管理的支援下,這邊則是摸索了encodeURIComponent以及decodeURIComponent這樣的函式,將要查詢的參數在a頁面進行編碼並丟入到URL中,跳轉到b頁面後再進行解碼.並fetch我要的資料.最後是有成功的,只是覺得自己像薪水小偷哈哈哈,效率並不高. 這個方法感覺並不建議應用在需要輸入有個人資料的內容中,因為編碼的方式是雙向的,資料可以編碼也可以解碼,所以....像個資這類的內容就應該不建議塞在URL中用這種方式傳輸.至於要用什麼方法,這也是我想知道的. ## 遇到的問題3:不同裝置的問題 這個並非第一個樣式的問題,而是我目前覺得還沒有解的問題,就是我在網頁中需要獲取使用者的位置,因此用了navigator.geolocation 這個API,但神奇的是,在本機中都可以抓得到資料,打開Dev Tools檢查回傳的狀態碼與經緯度也都是沒有問題,但是在手機中雖然會顯示是否能夠取得使用者位置的提示,但按了同意後卻一直無法獲取資料,而且尷尬的是,我無法在手機中打開Dev Tools,所以我也不知道問題發生在哪....,過去有使用過navigator.geolocation 好像也沒有碰過這樣的問題 想跟各位請教的是,有什麼方式可以查看手機上的問題嗎? ## 遇到的問題4:不同的開發方式 這個是我自己很好奇的,雖然說我知道Vue是漸進式框架,但我卻不知道該如何漸進.我理解的漸進式是,有些頁面或元件可以自行選擇要不要使用Vue開發,還是這個漸進式的意思是可以自行選擇要使用多少Vue的套件工具呢(像是要不要使用Vue Router or Vuex). 會這樣問是因爲,假如現在有一份專案一共是十個頁面,我被分到了其中五頁,另外的同事則是負責另外五頁,誠如開頭所說,假如公司既定的開發方式並不使用框架與其他整合工具,我有可能使用框架進行開發並與之合作嗎?還是我這是一個很奇怪的問題,本來就應該要統一一個開發方式? --- 感謝看到這邊的各位,以上有些觀念上是我這位小菜雞自己摸索的,是可能不是正確的(例如有些函式、工具的用途或使用情境),因此歡迎大家指教與討論,這是我這禮拜可以跟大家分享的啦. 謝謝~~ --- PS:我自學八個月的時間有摸了原生JS、CSS、Vue.js、Tailwind、SCSS這樣的工具,本來我是很想要在第一份工作多了解與強化上述工具以及多人開發GitHub的部分,我了解這些終究只是工具且我自己也沒有到非常熟,只要可以完成專案目的即可,我的實力在哪裡我也知道,但以目前公司的開發模式來說,我需要考量沒有踏上趨勢的這個問題嗎?還是我多慮呢了?

[好文分享] 太屌了吧!?用Class(類)製作Jquery的效果!

## 目錄 ##### [【前端動手玩創意】等待的轉圈圈效果 (1)](https://ithelp.ithome.com.tw/articles/10311621) ##### [【前端動手玩創意】google五星評分的星星(2)](https://ithelp.ithome.com.tw/articles/10311643) ##### [【前端動手玩創意】CSS-3D卡片翻轉效果(3) (今天難度頗高,想挑戰再進來!)](https://ithelp.ithome.com.tw/articles/10311672) ##### [【前端動手玩創意】一句CSS做出好看的hero section!(4)](https://ithelp.ithome.com.tw/articles/10311691) ##### [【前端動手玩創意】創造一個Skill bar(5)](https://ithelp.ithome.com.tw/articles/10311756) ##### [【前端動手玩創意】遮蔽廣告(D卡未登入)腳本、自定義新增名單(6)](https://ithelp.ithome.com.tw/articles/10311999) ##### [【前端動手玩創意】前端canvas截圖的招式!竟然有三招,可存成SVG或PNG (7)](https://ithelp.ithome.com.tw/articles/10312001) ##### [【前端動手玩創意】讓你的PDF檔案更難被抓取(8)](https://ithelp.ithome.com.tw/articles/10312046) ##### [【前端動手玩創意】哇操!你敢信?花式寫todo-list,body裡面一行都沒有也能搞?(9)](https://ithelp.ithome.com.tw/articles/10312056) ##### [【前端動手玩創意】卡片製作,才不是!是卡片製作器!(10)](https://ithelp.ithome.com.tw/articles/10312066) ## 前情提要 各位知道jquery,這個JS的函式庫提供我們非常多實用的方法,包裝好給我們用。 其中底層邏輯都還是跑不出js原生的概念, 今天就讓我們用原生JS的類來創造一些Jquery幫我們打包好的方法吧! 來掀開它的奧秘底牌。 ## 程式碼內容 假設我們要創造一個叫做Dquery的東西,該怎麼做呢: ``` class Dquery { constructor(selector) { this.elements = document.querySelectorAll(selector); //噴出DOM來 } css(property, value) { for (let i = 0; i < this.elements.length; i++) { this.elements[i].style[property] = value; } return this; //修改style } addClass(className) { for (let i = 0; i < this.elements.length; i++) { this.elements[i].classList.add(className); } return this; //增加class } removeClass(className) { for (let i = 0; i < this.elements.length; i++) { this.elements[i].classList.remove(className); } return this; } on(eventType, callback) { for (let i = 0; i < this.elements.length; i++) { this.elements[i].addEventListener(eventType, callback); } return this; //監聽事件的運作 } html(htmlString) { if (typeof htmlString === 'undefined') { return this.elements[0].innerHTML; } else { for (let i = 0; i < this.elements.length; i++) { this.elements[i].innerHTML = htmlString; } return this; } } } function $(selector) { return new Dquery(selector); } ``` ## 觀念筆記 其實概念就是先把底層邏輯刷過一遍 最後return this 就達成jquery的效果了唷。 ## 心得 Jquery曾經非常流行,儘管後來式微了,卻還是有一批死忠的粉絲鍾愛著它的簡便, 事實上它就是JS,所以討人喜歡也是正常的, 這次學會了用ES6類的概念,會讓我們在前端的功力大幅提升唷!!

給OOP初學者的建議:先搞懂「資料跟行為在一起」就好,其它的慢慢來

初學者接觸OOP,幾乎都會有以下疑惑: 我到底為什麼要學OOP?OOP解決了什麼問題?書上這些範例就算不用OOP也寫得出來吧? 然後覺得「繼承」、「多型」、「介面」、「抽象類別」等等的名詞很難,覺得OOP很難。 其實這些名詞雖然重要,但對新手來說,本來就很難在一開始就搞懂。 建議先搞懂「資料跟行為在一起」是什麼,以及它的好處在哪,就可以了,其它的慢慢來。 # 什麼叫做「資料跟行為在一起」? 假設我們在開發一個「中英文互助學習網」,鼓勵中文人士與英語人士登入討論。 這個系統的貼文、留言功能會顯示「發文日期」。 發文日期要根據使用者的註冊身份(台灣人、英語人士)顯示不同格式(台灣格式、西方格式)。 下面就以這個日期格式的功能舉例說明「資料跟行為在一起」是什麼意思。 ## 作法一:直接硬寫(不OOP、資料跟行為混在一起) 初學者通常會用最簡單、也最直覺的作法,直接硬寫出來,像這樣: ``` <?php $postDate = '2016-06-02'; # 假設資料庫取出來的發文日期長這樣 if (/* 判斷是否顯示台灣格式 */) { # 轉換成這樣 2016.6.2 $arr = explode('-', $postDate); $year = $arr[0]; $month = $arr[1]; $day = $arr[2]; echo "$year.$month.$day"; } else { // 西方格式 # 轉換成這樣 6/2/2016 $arr = explode('-', $postDate); $year = $arr[0]; $month = $arr[1]; $day = $arr[2]; echo "$month/$day/$year"; } ``` 這種寫法的資料(日期)跟行為(轉換成各種格式)混在一起。 它的優點是寫起來很簡單,缺點則有兩個: * 日期格式的邏輯會重複出現在很多地方,整段code會到處重複出現 * 整段code大概會塞在 `div` 或是 `span` 的裡面,導致它跟HTML混在一起,很亂 ## 作法二:自訂函數(不OOP、資料跟行為沒混在一起) 為了解決作法一遇到的問題,聰明的初學者很快就想到可以用「自訂函數」!就像這樣: ``` <?php function localFormat($date) { $arr = explode('-', $date); $year = $arr[0]; $month = $arr[1]; $day = $arr[2]; return "$year.$month.$day"; } function englishFormat($date) { $arr = explode('-', $date); $year = $arr[0]; $month = $arr[1]; $day = $arr[2]; return "$month/$day/$year"; } $postDate = '2016-06-02'; # 假設資料庫取出來的發文日期長這樣 if (/* 判斷是否為台灣人身份 */) { echo localFormat($postDate); } else { // 英語人士身份 echo englishFormat($postDate); } ``` 這種寫法將行為(轉換成各種格式)用自訂函數給獨立出來,也大幅改善了作法一遇到的問題。 對小型的網頁程式來說,這招非常好用,不但開發快速、簡單,還漂亮地將資料跟行為拆開。 但是程式規模變大之後,為了將各種行為拆出來,會寫出很多自訂函數,類似這樣: ``` ?php function localFormat($param) { // blah blah ... } function englishFormat($param) { // blah blah ... } function someTask($param) { // blah blah ... } function anotherTask($param) { // blah blah ... } function otherTask($param) { // blah blah ... } //... ``` 於是又衍生出三個問題: 1. 像localFormat、englishFormat這樣的函數名稱意義模糊,看不出是處理日期、人名,還是什麼東西的格式 2. 這些自訂函數各有不同的行為,全部放在一起顯得很亂,應該要想辦法分類、整理這些函數 3. 像localFormat、englishFormat這樣的函數,只吃特定格式的參數,最好能跟某種資料的形式綁在一起,以後要改程式時,能讓相關的資料跟行為一起被看到 問題1很好解決,只要替函數名稱加前綴字變成dateLocalFormat、dateEnglishFormat就行了。 問題2也很好解決,只要多開幾個檔案,把相關的函數放進同一個檔案就行了。 問題3就很棘手,資料跟行為拆開之後,如何在概念上又找方法整理在一起? ## 作法三:使用class(OOP、資料跟行為在一起) 正是這些處理資料、整理行為的問題,導致了OOP的誕生: ``` <?php class Date { public $year; public $month; public $day; public function __construct($date) { $arr = explode('-', $date); $this->year = $arr[0]; $this->month = $arr[1]; $this->day = $arr[2]; } public function localFormat() { return $this->year . '.' .$this->month . '.' . $this->day; } public function englishFormat() { return $this->month . '/' .$this->day . '/' . $this->year; } } $postDate = '2016-06-02'; # 假設資料庫取出來的發文日期長這樣 $date = new Date($postDate); if (/* 判斷是否為台灣人身份 */) { echo $date->localFormat(); } else { // 英語人士身份 echo $date->englishFormat(); } ``` OOP的寫法,一次解決了前述三個問題: 問題1 => 現在從類別名稱就可以知道底下方法的意義了 問題2 => 現在相關的函數都整理進同一個類別底下成為方法了 問題3 => 現在資料的形式都統一在constructor處理一次,之後不管新增多少方法都不用處理資料了 這就是所謂的「資料跟行為在一起」,也正是OOP的核心概念。 利用這種方式整理程式碼、寫出一個又一個的類別,可以大幅提昇程式碼的品質。 # 結論 上述的作法一跟作法二並沒那麼糟糕,但確實會帶來一些問題。 對於小型的網頁程式來說,可能還算夠用。 但是隨著程式規模變大,如果將概念上相關的資料跟行為整理在一起,會很有幫助。 實務上也可以先從作法二開始寫起,直到發現某些資料跟行為關係密切,再拉出來整理成類別即可。 至於很多OOP教學會提到的「繼承」、「多型」、「介面」、「抽象類別」等等名詞,一時搞不懂沒有關係,你可能實務上也暫時用不到。之後找時間慢慢搞懂它們的用途就好。 光是知道「將資料跟行為放在一起」的技巧,就能夠開始寫OOP程式碼了。 (註:本篇文章的程式碼純屬教學用途。實務上PHP已經有DateTime類別可以使用,或是用更漂亮的Carbon類別。) ## Q&A Q1:我常常設計一些類別,只有資料沒有行為,聽起來OK嗎? 不OK,這很不OOP,而且沒意義。 乾脆直接用關聯式陣列去表示那些資料就好。 Q2:我常常設計一些類別,只有行為沒有資料,聽起來OK嗎? 這個要看情況,不一定。 但唯一可以確定的是,這種作法很不OOP。 因為OOP的核心是「資料跟行為在一起」。 這也是為什麼你會看到有人明明寫了類別、用了物件,別人卻說「這不夠OOP」。 然後你又會看到像JavaScript這樣連「類別」關鍵字都沒有(ES5以前),卻能夠寫出很OOP程式碼的關係。 判定的標準都是一樣的,而且也就只有這麼一個標準:資料跟行為有沒有在一起。 Q3:一個類別包含的概念是越大越好,還是越小越好? 不一定。不過我們從作法一到作法三的過程,有一個明確目的:希望讓程式碼更好懂。 如果聲稱一個類別包含的概念很大(例:設計LanguageHelpWebsite類別,用來代表「中英文互助學習網」需要的所有功能),那會把幾乎整個網站的所有行為跟資料都放進去,成為所謂的God object。它可沒有讓程式碼更好懂。 相反地,如果聲稱一個類別包含的概念很小(例:分別設計LocalDate、EnglishDate類別),雖然意義可能更精準了,但用一整個Date類別的概念去思考,程式碼會更容易理解,也就是所謂的內聚性(Cohesion)更高。 所以要替OOP就是「資料跟行為在一起」加個但書: 要以方便理解程式為前提,將資料和行為放在一起。

# JS油猴系列-遮蔽廣告(D卡未登入)腳本、自定義新增名單

## 前情提要 逛論壇或網站常常有惱人的蓋板廣告,要馬就是要你登入、註冊, 要馬就是搞一堆課程的販售廣告, 對重視使用者體驗的人來說,真的是一場噩夢! 為了解決這個問題,我模擬了AdBlock的其中一個功能,刪除頁面上的元素! 乾乾淨淨才是王道阿。 ## 效果 按下ctrl+Q啟動刪除元素模式: ![](https://i.imgur.com/411nh3Q.png) 被選取的會加上邊框色彩,讓人確認是否要刪除: ![](https://i.imgur.com/zPEKMhC.png) 點選確認後: ![](https://i.imgur.com/nnOY4Ji.png) 煩人的元素就此消失在這個永恆的宇宙裡。 ## 觀念筆記 ### 套件一:toastr ```javascript= //toast.js cdn匯入 const toastJS = ` <link href="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/2.1.4/toastr.min.css" rel="stylesheet" /> <script src="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/2.1.4/toastr.min.js"></script>` $('body').append(toastJS); ``` ![](https://i.imgur.com/lNDch3V.png) [測試效果反應網站](https://codeseven.github.io/toastr/demo.html) ![](https://i.imgur.com/v95GUfO.png) [[十分鐘學習] toastr - 簡易提示訊息](https://ithelp.ithome.com.tw/articles/10197861) ### 套件二:SweetAlert2 ```javascript= //設定cdn使用Sweetalert套件 let Sweetalert2=`<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>` $('html').append(Sweetalert2) ``` ![](https://i.imgur.com/qUeTUlj.png) ![](https://i.imgur.com/FJH8EMX.png) 有提供很多API範例,還可以自己定義可愛的小動物XD [官方網站](https://sweetalert2.github.io/) ### 監聽鍵盤組合鍵 ``` document.addEventListener('keydown', function(e){ if(e.which==81 && e.ctrlKey==true){ //..... } ``` ### Object.assign 動態修改樣式 ![](https://i.imgur.com/AzZMRCc.png) [用JS動態修改CSS的三種寫法,花式JS玩弄樣式,嚇死你的同事!](https://codelove.tw/@JsLover0018/post/Ja64Kx) ## 油猴程式碼 ```javascript= // ==UserScript== // @name 刪除廣告元素 // @namespace http://tampermonkey.net/ // @version 0.1 // @description try to take over the world! // @author You // @match *://*/* // @require https://code.jquery.com/jquery-3.6.3.min.js // @icon https://www.hexschool.com/ // @grant none // ==/UserScript== (function() { //--------------------------------------- // 宣告變數 let set let Check = true; let List=[] //設定選取的border色彩效果 let styleNeon = `@keyframes neon-color { from { filter: hue-rotate(0deg); } to { filter: hue-rotate(360deg); } }` $('style:last').append(styleNeon) //設定cdn使用Sweetalert套件 let Sweetalert2=`<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>` $('html').append(Sweetalert2) //使用者點選某個元素 執行刪除元素function function SetDeleteEl(e){ e.preventDefault(); set=e.target.class console.log(set) const border={ border:"4px dotted red" } const Neon={ animation: "neon-color 2.5s linear infinite" } const NoBorder={ border:"none" } const StopNeon={ animation: "" } Object.assign(e.target.style,border) Object.assign(e.target.style,Neon) //e.target.remove() if (Check==true){ Swal.fire({ title: '確定要刪除這個元素?', showDenyButton: true, showCancelButton: false, confirmButtonText: '確認', denyButtonText: `取消`, }).then((result) => { /* Read more about isConfirmed, isDenied below */ if (result.isConfirmed) { e.target.remove() List.push(e.target.className) localStorage.setItem('List',List); Check=false; Swal.fire('成功刪除此元素!', '', 'success') } else if (result.isDenied) { Check=false; Swal.fire('動作已取消', '', 'info') Object.assign(e.target.style,NoBorder) Object.assign(e.target.style,StopNeon) }; }); } //選取流程結束後 解開選取流程的事件綁定 $('body').unbind('click',SetDeleteEl) } //toast.js cdn匯入 const toastJS = ` <link href="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/2.1.4/toastr.min.css" rel="stylesheet" /> <script src="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/2.1.4/toastr.min.js"></script>` $('body').append(toastJS); // 當使用者按下Ctrl+Q 就執行主程序 document.addEventListener('keydown', function(e){ if(e.which==81 && e.ctrlKey==true){ RemoveListItem(); toastr.options = { // 參數設定[註1] "closeButton": false, // 顯示關閉按鈕 "debug": false, // 除錯 "newestOnTop": false, // 最新一筆顯示在最上面 "progressBar": false, // 顯示隱藏時間進度條 "positionClass": "toast-bottom-right", "preventDuplicates": false, // 隱藏重覆訊息 "onclick": null, // 當點選提示訊息時,則執行此函式 "showDuration": "300", // 顯示時間(單位: 毫秒) "hideDuration": "1000", // 隱藏時間(單位: 毫秒) "timeOut": "2000", // 當超過此設定時間時,則隱藏提示訊息(單位: 毫秒) "extendedTimeOut": "1000", // 當使用者觸碰到提示訊息時,離開後超過此設定時間則隱藏提示訊息(單位: 毫秒) "showEasing": "swing", // 顯示動畫時間曲線 "hideEasing": "linear", // 隱藏動畫時間曲線 "showMethod": "fadeIn", // 顯示動畫效果 "hideMethod": "fadeOut" // 隱藏動畫效果 } toastr.success( "已開啟刪除元素模式!" ); $('body').on('click',SetDeleteEl) Check=true }}) function RemoveListItem(){ if (localStorage.getItem('List')!=null){ item=localStorage.getItem('List').split(',') for (i=0;i<item.length;i++){ item[i]='.'+item[i] item[i]=item[i].replaceAll(' ','.') try{ document.querySelector(item[i]).remove()} catch{} } // item='.'+item // item=item.replaceAll(' ','.') // document.querySelector(item).remove() } } //-------------------------------------------------------- })(); ``` ## 心得 短短150行左右的程式碼,就寫得好辛苦!(汗 過去寫過很多次類似的東西,所以基本上沒有卡關的地方, 只是設計邏輯、嘗試的過程還是比想像的還要耗精神( ´•̥̥̥ω•̥̥̥ ) 但寫出來比過去快很多,也比過去好看超級多的。 給自己一個讚讚! 重新把localstorge複習一遍,Object.assign、套件使用等。 算是一個確確實實的實力鞏固過程。 ## 延伸 未來可以新增控制黑名單元素的UI。 可以新增、刪除,看有哪些元素被列入要刪除的黑名單。

[作業問題]HTML&CSS 第6課 Loading Page

您好,請問幾個問題。 1.為什麼我使用position:relative,網頁會出現很大的空白,我該如何解決。 2.使用絕對位置,我該如何讓我的網頁隨著比例縮放。 問題1 : ![](https://i.imgur.com/wzXvqGk.jpg) 問題2: ![](https://i.imgur.com/4a7OA6u.jpg) ![](https://i.imgur.com/BzUIBdJ.jpg) 這是網頁全開的時候 ![](https://i.imgur.com/YGNQAfx.jpg) HTML: ``` <!DOCTYPE html> <html> <head> <meta charset = "UTF-8"> <title>佳加安全帽</title> <link rel = "stylesheet" href = "style.css"> </head> <body class = "page"> <div class = "navbar"> <div class="container"> <div class = "logo"> <a href = "#"><img src = "jiajia.jpg"/></a> </div> <div class="menu"> <ul class="choose"> <li><a href = "">所有商品</a></li> <li><a href = "">特價商品</a></li> <li><a href = "">安全帽</a></li> <li><a href = "">藍芽耳機</a></li> <li><a href = "">裝備衣物</a></li> <li><a href = "">配件</a></li> <li><a href = "">包包</a></li> </ul> </div> <div class="user"> <ul> <li><a href = "">Log in 登入</a></li> <li>|</li> <li><a href = "">Sign up 註冊</a></li> </ul> </div> </div> </div> <div class="background"> <div class="content"> <h1>在危險的世界中,給你多一份安全</h1> </br> </br> <p>留下您的email,獲得新商品及最新優惠資訊</p> </br> <input type= "email" name = "email" value = "Your email"> </br> <input class="submit" type = "submit" name= "submit" value = "訂閱"> </div> </div> </body> </html> ``` CSS: ``` *{ margin: 0px; padding: 0px; list-style-type: none; text-decoration: none; } .navbar{ background-color: #272727; height: 50px; width: 100%; } .logo img{ height: 50px; } .menu{ position: relative; top: -50px; line-height: 45px; left: 500px; } .menu li{ float: left; } .menu a{ color: #D9B300; display: block; padding: 0 10px; } .menu a:hover{ background-color: #D9B300; color: #272727; } .user{ position: relative; top: -50px; left: 800px; line-height: 45px; } .user li{ float: left; color: #D9B300; } .user a{ color: #D9B300; display: block; padding: 0 10px; } .user a:hover{ background-color: #D9B300; color: #272727; } h1{ color: white; } p{ color: white; } .background{ background-image: url("motor.jpg"); background-size: cover; background-repeat: no-repeat; height: 660px; text-align: center; } .content input{ width: 400px; height: 40px; } .content h1{ font-size: 40px; } .content p{ font-size: 20px; } .content{ position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); } .submit{ font-weight: bold; font-size: 20px; background-color: #D9B300; color: #272727; border-radius: 10px; border: 0px; } .submit:hover{ background-color: #272727; color: #D9B300; }

JavaScript 系列八:第5課 ── 體重追蹤應用程式

## 課程目標 - 能夠寫出體重追蹤應用程式 ## 課程內容 找套件時,如果官方沒有提供特定框架的版本,通常會有開發者,自行包裝一個,分享給大家使用 搜尋 `how to use 套件名稱 in 框架名稱` 大概就找得到相關資源了 舉例來說,這款圖表套件,官方沒有提供框架版本 https://www.chartjs.org/ 但是社群就有人做好了 https://vue-chartjs.org/ --- 介紹一個網站 https://dribbble.com/ 業界設計師,經常在上面搜尋別人的成品、找靈感、分享靈感 除了在 google 搜尋關鍵字,也可以常常到 Dribbble 搜尋 --- 這一課來寫體重追蹤應用程式 關鍵字 `weight tracking` ## 課後作業 請使用 https://replit.com/ 來寫作業 這次作業的規格如下: - 這種程式應該要讓人註冊登入使用,需要後端配合,但我們簡化吧:免登入、把資料存在 local storage 就好 - 此程式能夠新增一筆體重資料,input 欄位有「體重」、「日期」 - 有清單列表顯示每一筆輸入的資料,按照日期排序。每筆資料旁邊有刪除按鈕 - 使用 Chart.js 將體重的走勢,用折線圖(Line Chart)呈現 - 請「不要」使用社群包裝的版本(vue-chartjs),學著自己在框架內導入套件 --- 提示:vue 跟 chart.js 整合的時候,有一個地雷!會導致 `RangeError: Maximum call stack size exceeded ` 要解決這個地雷,請參閱這邊的討論 https://codelove.tw/@birdie2019/post/Ja69K3 --- 做出以上功能,你就完成這次的課程目標了!

JavaScript 系列八:第4課 ── 行事曆應用程式

## 課程目標 - 能夠寫出行事曆應用程式 ## 課程內容 現在新推出的大部份 javascript 套件,都會提供 native(原生)、React、Vue 三種版本,方便使用 舉例來說,這款行事曆套件,就有多種版本 https://fullcalendar.io/ 也有易安裝的 CDN 版本 https://fullcalendar.io/docs/initialize-globals --- 所謂的 React、Vue 或是任何框架版本,其實就只是把套件,根據框架規格,封裝成元件而已 (元件的觀念,之後會教,先別擔心) 套件會大量跟 DOM 互動,框架也會跟 DOM 互動,兩者容易衝突,使用上通常會 bug 一大堆 所以官方會推出套件版本,改掉一些底層寫法,方便框架用戶使用 如果沒有,那就由開發者自己小心管理,通常也沒太大問題 就是把初始化相關放在 `mounted` 裡面,然後狀態更新時,找方法與套件狀態同步,就這樣而已 --- 這一課來寫行事曆應用程式 關鍵字 `calendar app ui` ## 課後作業 請使用 https://replit.com/ 來寫作業 這次作業的規格如下: - 這種程式應該要讓人註冊登入使用,需要後端配合,但我們簡化吧:免登入、把資料存在 local storage 就好 - 有一個「新增活動」按鈕,點擊可以輸入「活動名稱」、選擇「活動日期」與「活動時間」 - 不用做成「開始、結束」兩個時間點,就做成開始時間就好 - 日期時間的 UI,請使用 https://github.com/xdan/datetimepicker - 上述功能,可以做成 modal 視窗(輸入欄位放在視窗內),也可以直接把輸入欄位都放在畫面上 - 使用 FullCalendar 呈現行事曆,將活動顯示在對應日期 - 點擊行事曆內的活動,可以刪除活動。請使用 javascript 內建的 `confirm` 函式,確認「是否刪除此筆活動?」後刪除 - 請「不要」用官方 Vue 版本,請用 CDN 版本,學著自己在框架內導入套件 做出以上功能,你就完成這次的課程目標了!

JavaScript 系列五:第5課 ── 學會 AJAX 錯誤處理

## 課程目標 認識 AJAX 錯誤處理 ## 課程內容 在前一課,我們說過以下的話 > 有些任務現在還不會立刻執行,但我先把要執行的任務交待清楚,時間點到的時候,就執行 > 以 UI 動作來說,時間點就是 `onclick` 之時、`onchange` 之時 > 以 AJAX 動作來說,時間點就是 `拿到主機回應` 之時 實際上,AJAX 的時間點,除了 `拿到主機回應` 之時,還有一個,就是 `發現主機回應失敗` 之時 把原本的範例 ``` fetch('https://fakestoreapi.com/users/1') .then(res=>res.json()) .then(json=>console.log(json)) ``` 故意打錯字試試看,然後加上錯誤處理機制 ``` fetch('https://fakestoreapi.com/users1') .then(res=>res.json()) .then(json=>console.log(json)) .catch(error => { alert(error); }) ``` 就跟 `.then()` 函式把任務傳進去類似,`.catch()` 一樣是把任務傳進去,只是改傳「AJAX 失敗的時候要執行的任務」 --- 這邊只是舉例,才故意打錯字 實務上,AJAX 失敗可能是 - 主機故障、或者過度忙碌無法回應 - 呼叫 API 時,登入驗證資訊過期 - API 設計成有額度限制,用戶額度耗完了,被主機拒絕 - 用戶自己的網路斷線了(網頁打開時正常,但發送 AJAX 時已斷線) 等等很多可能,要看 API 主機是如何設計的 --- 實務上,`.catch()` 內要提醒使用者,剛才的動作失敗,請他重新嘗試 我個人通常就用 alert 跳一個訊息「抱歉,系統出現錯誤,請稍後重新嘗試。若持續出錯,請聯絡客服信箱」就結束了 但在公司的大型專案,需要更好 UX 的話,請與設計師討論後決定如何優雅地處理錯誤情境 ## 課後作業 接續前一課的作業,請加上錯誤處理機制 用 alert 跳出 `抱歉,請稍後重新嘗試。` 就好了 接著,請把電腦的 wifi 或有線網路,斷線 然後點擊「Load Products」按鈕,應該會看到錯誤提示訊息 做出以上功能,你就完成這次的課程目標了!

JavaScript 系列五:第1課 ── 學會 Cookie 相關功能

## 課程目標 認識並且能使用 Cookie 相關功能 ## 課程內容 大名鼎鼎的 cookie,很多人在科技新聞上都聽過 某某公司利用網頁 cookie 追蹤個資、某某公司偷偷用 cookie 分享個資 這類新聞提到的 cookie,就是本課在說的 cookie 目前為止的作業,你會發現只要重新整理網頁,畫面上的所有東西就都歸零回預設值了 因為我們說網頁 HTTP 協議是「無狀態」的,也就是每次打開網頁的「狀態」不會被保留 這樣的設計當然有好處以及方便的地方,因為每次打開網頁都是獨立事件、彼此不會互相影響,開發起來單純很多 但是在實務上,經常需要「有狀態」才能完成某些功能,例如「已登入帳號」的狀態,否則網站會變很難用 Cookie 技術就是為了這個原因而誕生 --- Cookie 主要有兩個特性 - cookie 的內容,主機端也能存取 - cookie 的內容,網頁重新整理之後還會保留 Cookie 會出現在 HTTP Request 內,一起送到主機 會員登入功能、各種廣告追蹤功能,就是這樣做到的 HTTP 協議不熟沒關係,反正就是前端工程師設定過 cookie 值之後,後端工程師也能在主機端拿到那些值就對了 --- 注意,由於 cookie 會包含一些網站上的敏感資訊,jsfiddle 等等線上程式碼實驗工具、以及各種免費架站工具,幾乎通通都關閉了 cookie 功能 我目前找到一個可以用 cookie 的架站工具 https://replit.com/ 本課請使用 replit 來跑範例程式碼、寫作業 註冊登入之後,點 Create -> Templates -> 選 HTML, CSS, JS 那個 -> Create Repl 就可以開始寫了,但是右邊的預覽視窗,因為是 iframe,一樣不能用 cookie 請點擊右上方的 Open in a new tab,就可以正常跑 cookie 功能了 --- 來看一些範例程式碼吧 ``` Your Age: <input type="text"> Your Name: <input type="text"> <button onclick="save()">Save</button> <script> if (document.cookie) { alert(document.cookie); var arr = document.cookie.split(';'); var myage = arr[0].split('=')[1]; var myname = arr[1].split('=')[1]; document.querySelectorAll('input')[0].value = myage; document.querySelectorAll('input')[1].value = myname; } function save() { var myage = document.querySelectorAll('input')[0].value; var myname = document.querySelectorAll('input')[1].value; document.cookie = 'myage=' + myage; document.cookie = 'myname=' + myname; alert('saved!'); } </script> ``` 這個範例中,輸入年齡、名字一次,接著重新整理網頁,會發現資料一樣存在欄位裡面,不用重新輸入! 存取值,都是透過 `document.cookie` 這個物件屬性,值的格式是 `name=value` 雖然 `document.cookie=` 寫了兩次,但第二次並不會蓋掉第一次的值,而是兩個都存進 cookie 了 (這個設計,很糟糕,沒錯,讓人看得很混亂。應該是瀏覽器的設計者,有他們的苦衷,我們先不細究原因,先知道怎麼用就好) 然後,讀取的時候,多個值會用分號 `;` 隔開,所以讀取時我用了 `.split()` 這個字串函式 除此之外,cookie 還可以設定「使用期限」以及「限定網域」,但我這邊就先不示範 總之,cookie 的效果大概就是這樣,稍微理解就好。然後這些值,後端工程師在伺服器端,也會收到,就這樣! --- 如上所示,cookie 寫起來,有點麻煩 實務上,每次都這樣手寫,太囉唆,通常會直接找套件來用,我是用這款 https://github.com/js-cookie/js-cookie 用來操作 cookie 的 API,漂亮多了! --- 關於 cookie 的 debug 除錯,也要知道一下 打開瀏覽器開發者工具 -> Application -> Cookies 可以看到網站上有哪些 cookie,也可以直接在這邊修改、刪除 cookie --- cookie 還有一些特性,以及大小限制、使用限制 這邊不細談,稍微知道怎麼用 cookie 就好 有興趣的話,請上網搜尋一下,多研究一些 cookie 的細節 ## 課後作業 請使用 https://replit.com/ 來寫作業 假設你正在幫客戶寫一個「成人限制級網站」 頁面第一次打開會顯示蓋板警告,下方有兩個按鈕 ``` 警告︰您即將進入之網頁內容需滿十八歲方可瀏覽。 根據「兒童及少年福利與權益保障法」規定,本網站已於非闔家皆宜之網頁加以標示。若您尚未年滿十八歲,請點選離開。若您已滿十八歲,亦不可將本站之內容派發、傳閱、出售、出租、交給或借予年齡未滿18歲的人士瀏覽,或將本網站內容向該人士出示、播放或放映。 您年滿十八歲嗎? [離開] [是,我已年滿十八歲] ``` - 點擊離開,把用戶跳轉到 google 首頁 - 點擊確認,就關閉蓋板警告,在網頁上顯示一張美女 or 帥哥圖片:參考圖庫 https://unsplash.com/ - 只要按過確認,重新整理之後,蓋板警告就不會再跳出來 做出以上功能,你就完成這次的課程目標了!

JavaScript 系列三:練習3 ── modal 互動視窗元件

## 課程目標 認識並且能實做 modal 元件 ## 課程內容 modal 中文叫「互動視窗」元件,也有人叫「燈箱」或者「視窗」 這是幾乎所有網站都會用到的元件 台灣各大媒體網站常見的「蓋板廣告」,就算是一種「視窗」 各大社群網站,逛一逛就跳出「視窗」強迫你登入 點擊照片或者貼文,以前常常會開啟新網頁,現在常常設計成打開「視窗」直接就可以看內容 modal 跳出時,通常會將整個背景變成半透明黑色或白色,來讓視窗內容更顯眼 並且 modal 會有按鈕可以關閉 請上網搜尋 `popup modal ui` `lightbox ui`,四處觀摩一下業界常見的設計 --- 要寫出這種視窗的效果,其實 css 的部份還比 js 的部份難一些 請上網搜尋 `燈箱 css` `popup modal css` `popup modal css` 了解各種不同的寫法與技巧 半透明背景遮罩的英文術語叫 `black overlay` 請上網搜尋 `css 黑色半透明遮罩` `full page black overlay css` 了解各種如何做到此效果。不過,若是做不出來,這個效果也是可以省略不做 ## 課後作業 請使用 https://jsfiddle.net 用以下 html 為基礎(你可以稍微修改),接著寫出 css 與 js 的部份 ``` <button onclick="loginModal()">點我登入帳號</button> <hr> <button onclick="postModal()">點我新增貼文</button> <div class="modal" id="login-modal"> <div>帳號:<input type="text"></div> <div>密碼:<input type="password"></div> <hr> <button class="btn-close">關閉</button> </div> <div class="modal" id="post-modal"> <div>標題:<input type="text"></div> <div>內文:<textarea></textarea></div> <hr> <button class="btn-close">關閉</button> </div> ``` --- 這邊共有兩個按鈕,模擬兩種使用情境 兩個視窗元件,一開始預設是隱藏的,不會在畫面上看到 點擊登入按鈕,會跳出登入視窗。可以點擊視窗內的關閉按鈕,來將視窗關閉 點擊貼文按鈕,會跳出貼文視窗。可以點擊視窗內的關閉按鈕,來將視窗關閉 --- 請稍微加一些 css 屬性,弄得漂亮一點 `<hr>` 只是方便隔開元素,方便別人查看元件用的,醜醜的留在畫面上沒關係 --- 做出以上功能,你就完成這次的課程目標了!

初次轉職寫程式:作品集有用嗎?要做什麼作品?面試官會看嗎?

很多朋友轉職寫程式,在補習班或者線上課程,告一段落之後,開始找工作之前,會整理作品集 關於作品集,簡單給大家一些建議 ## 作品集有用嗎? 公司在徵人的時候,其實來應徵的人五花八門 滿多人看起來,根本不會寫程式,連最基本的小網頁或者小程式都寫不出來 連基本技能都沒有準備好,感覺是到處碰碰運氣、履歷亂誇大就到處丟。公司面試時,最怕遇到這種狀況 作品集,至少代表,你寫得出基本東西。很多人根本寫都不會寫,就去應徵了,作品集至少可以讓公司避免踩雷 話說回來,如果你的作品集,只是補習班的幾個分組專案,糊裡糊塗地完成了,就跟在學校敷衍交報告一樣,你對細節其實不了解,那這種作品集,當然幫助不大,對你的信心也沒有多少幫助 ## 要做什麼作品? 所以該做什麼作品呢? 最好做一些你真的需要的「應用程式」,寫起來才有動力、才好玩,內容也才扎實 簡單舉例,如果你在受訓的過程是這些: ### 前端工程師 做個待辦事項清單工具吧!按照自己的喜好設計,做完之後找地方上線 在找工作的這幾個星期,實際拿這個工具來做紀錄,投履歷時、面試時,很自然可以分享你的心得跟小熱情 對面試官來說,看到面試者有即戰力(即便是有一點點)、對自己的程式有熱情(即便只有一點點),都會加分不少 請參考 https://todomvc.com/ 這是各種前端工具寫的 todo list 應用程式,你還可以比較自己的程式碼,與社群所寫的差異 ### 後端工程師 我鼓勵後端的入行者,寫一個「個人專屬部落格」 這個部落格要有以下功能 - 首頁列出文章清單 - 能簡單單篇文章瀏覽 - 自己可以登入後台 - 在後台可以新增、編輯、刪除文章 有餘力的話,還可以加個留言功能 這種部落格,會實際做完資料的 CRUD 基本功能,還有簡易的註冊、登入、驗證 找地方把這個部落格上線,或者買網址、租主機,實際上線 在找工作的這幾個星期,實際拿這個部落格,來寫文章、技術筆記、經驗分享 面試官絕對會覺得你是積極的人、有備而來 (錄取之後就停止寫網誌的習慣也沒關係) ### 全端工程師 我鼓勵全端的入行者,寫一個「個人行事曆工具」並且是 single page application (SPA) 這個行事曆要有以下功能 - 有一個行事曆頁面 - 有個按鈕可以新增活動 - 點擊行事曆內的活動,可以編輯、刪除 - 有一個清單業面,可以用條列式顯示全部活動 - 全程使用 ajax,不能整個刷新頁面 這種行事曆,會實際做完資料的 CRUD 基本功能,還有基本的 SPA routing 在找工作的這幾個星期,實際拿這個行事曆,紀錄生活是像、活動 面試時分享,面試官絕對會覺得你是積極的人、是個即戰力 ## 結論 除此之外,做個人履歷表的網頁也不錯 可以搜尋 'Portfolio website examples' 看看各種漂亮設計 實際把履歷做成網頁,也可稍微證明自己能力 在工程師生涯,不斷地做自己的 side project 是一個有趣、進步的好習慣 甚至有一天,你做的某個 side project 大受歡迎,還可能變成一個獨立的小產品呢 有空可以逛逛 https://www.producthunt.com/ 看看大家都在做什麼 side project 或許模仿其中一些,做個簡易版本,你會學到很多的~! --- 您有沒有什麼好的點子、推薦的 side project 點子給初心者呢? 歡迎留言分享!