# 0414 網頁中的互動及行為 ###### tags: `JavaScript` - [投影片連結](https://hackmd.io/@pastleo/H17nXC9ru#/) - [隨堂練習包](https://drive.google.com/file/d/119Y4C1RKUiOLr3KjsFZq_mpFmyChxS9s/view) * 直接使用 VScode 的 Live Server * 在 Ruby 裡面執行一個 Server ```shell= $ ruby -run -ehttpd . -p8000 ## 如果沒有成功的話可以安裝套件 webrick (ruby 3.0 之後沒有內建) $ gem install webrick ``` ## 瀏覽器內建的 DOM API - Vanilla JavaScript - 只使用瀏覽器內建的 DOM API 執行 JavaScript - 所有框架的底層都是 DOM API ### 在網頁中加入 JavaScript 程式碼 - 使用 `script` tag - 最好放在 `head` 或 `body` 裡面 ```html= <script> <!-- JS程式碼 --> </script> ``` - 使用 console.log 確認沒有有執行成功 - 也可以用 debugger ``` javascript <body> <script> console.log(123) </script> </body> ``` ![](https://i.imgur.com/zmlGAHh.png) ### 監聽事件 `.addEventListener()` - 告訴這個元件,之後收到什麼事件後做什麼事情 - `.addEventListener()` 方法可以用來綁定元素的事件處理函數 - 第一個參數 eventType 是事件名稱( 範例中為 ``'click'`` ) - 第二個參數 listener 是事件處理函數( 範例中為 `function(){...}` ) - 監聽型態: - ==主詞.動詞("事件", Callback Function)== - 網頁裡的元素.監聽("監聽的事件", 要叫元素做的事情) 例: ```javascript= <style> body { background: #353535; margin: 0; } body.light { background: #d4c370; } </style> <script> document.body.addEventListener('click', function() { document.body.classList.toggle('light') // toggle 讓 class 有 light 跟沒 light // 因為有無 class 是在 CSS 中是不一樣的樣式 }) </script> ``` - 元素選取方式 1. `document.body` : 選取檔案裡的 `body` 2. [`.classlist`](#classList) : class 清單 (因為可以有很多 class) - `document.body.classList` : 選取檔案裡的 `body` 的 class 清單 3. `document.body.className` : 選取檔案裡的 `body` 的 class 名稱 4. `.getElementById("id 名稱")` : 用 ID 選取物件 - `document.getElementById("cat")` : 選取檔案裡 ID 叫 cat 的元素 5. ``.textContent = ''`` : 標籤裡面的內容 6. ``.innerHTML = ''`` : 標籤裡的內容(再套用 HTML) 7. ``.querySelector( CSS 選取器 )`` : 用 CSS 選取器指定元素(只會選到第一個) 8. ``.querySelectorAll( CSS 選取器 )`` : 要跑 forEach 迴圈) - 監聽的事件 1. ``"click"``: 「點擊」這件事(滑鼠點下去的時候) 2. ``"DOMContentLoaded"`` : 當整個網頁被讀取後會觸發後面的事件 - [MDN 的解釋](https://developer.mozilla.org/en-US/docs/Web/API/Window/DOMContentLoaded_event) 4. [事件型態 - 可以監聽的事件](https://www.fooish.com/javascript/dom/event.html) - Callback function - ``.toggle()`` - 狀態對調(沒有的時候 add, 有的時候 remove) - ``.add()`` - 加上某個東西 - ``.remove()`` - 移除某個東西 - ``.createElement('HTML element')`` - 新增一個元素(要找個東西接它) - ``parent.appendChild('element')`` - 把它塞到某個元素的最後一個子元素位置 - ``.insertAdjacentElement('位置', 'element')`` - 可自行設定要把元素塞到哪裡 - [手冊說明](https://developer.mozilla.org/zh-TW/docs/Web/API/Element/classList) ![](https://i.imgur.com/8mHEagy.png =600x) - 由於網頁是由上往下讀取,所以 script 的位置會影響到程式執行與否,因此加上 DOMContentLoaded 事件,可以把整個 HTML 讀完才執行 JS ```html= <script> //↓請你把全部html讀完再來執行JS的程式 document.addEventListener('DOMContentLoaded', function() { //放要執行的JS程式↓ document.getElementById('toggle').addEventListener('click', function(){ document.body.classList.toggle('light') }) }) </script> ``` ### classList * add 新增 * 新增一個或多個類別 * 已經存在的不會再新增 * remove 移除 * 刪除 * toggle 切換 * 當 Div 上沒有這個CSS的時候,就新增給他,有的話就刪掉他 * contains 是否存在 * 檢查是否存在某個CSS * 回傳布林值 ## JS 的等號 - [JS的雙等號跟三等號:寬鬆模式 VS 嚴謹模式](https://medium.com/schaoss-blog/%E5%89%8D%E7%AB%AF%E4%B8%89%E5%8D%81-13-js-%E7%82%BA%E4%BB%80%E9%BA%BC%E5%88%A4%E6%96%B7%E7%9B%B8%E7%AD%89%E6%99%82%E4%B8%8D%E7%94%A8%E8%83%BD%E9%9B%99%E7%AD%89%E8%99%9F-d02fbf91492f) ```javascript= 1 == '1' // true // JS 背後自動轉型態 1 === '1' // false // 數字不等於字串 ``` ## 有關 window - window 是預設的 namespace - 瀏覽器剛發明的時候沒有分頁的概念,所以當初的 window 就是表示整個瀏覽器 - Date 處理時間相關,是個class,等於window.Date 所以隨時可以使用Date - ``(new Date()).toString()`` - 現在的時間並將他轉成字串 - location - 網址列 - window.location - 取得敘述網址列的物件 - window.location.href - 印出現在當下的網址列 - window.location.href = '指定的網址列' - 使用 JS 觸發換頁的動作 --- * debugger * 會使程式停在擺放`debugger`的那行,且可透過檢查確認這時候的變數,並可用 console 試著執行要嘗試的程式 --- * `parent.appendChild(el)` * 把傳進去的 el 傳入 parent 裡面的最後面 * el = element 縮寫 範例: ```html= document.querySelector('.right').appendChild(timeDiv) ``` timeDiv 就會被傳到 `class='right'` 這個 div 裡最後面 如圖的台北標準時間那幾行 ![](https://i.imgur.com/kTb2llo.png =500x) ## innerHTML - 可以替換 html 資料 - 避免放入使用者輸入的資料 --- `prompt()` 顯示一個對話框,對話框中包含一條文字,用來提示用戶輸入文字。 [MDN](https://developer.mozilla.org/en-US/docs/Web/API/Window/prompt) --- ## insertAdjacentElement - 指定位置 ## jQuery $ / $() 為解決早期 DOM API 相容性的問題 ```javascript= document.querySelector() = $() ``` - [jQuery API 列表](https://api.jquery.com/) - 引入 jQuery - [jQuery 官網](https://code.jquery.com/) - 點擊 3.0.0 minified ![](https://i.imgur.com/wuFKin0.jpg) console 檢查 $.fn.jquery ```javascript= document.addEventListener('DOMContentLoaded', function(){...}) // 等於 下方的 jQuery 用法 $(document).ready(function(){...}) document.querySelector('').addEventListener('click',function(){...}) // 等於 下方的 jQuery 用法 $('').click(function(){...}) ``` ### 計時器功能 (瀏覽器內建功能) ```javascript= timer = setInterval(function(){...}, 時間) // 每隔多久時間跳一次 // 單位為 1 ms 毫秒 clearInterval(timer) timeout = setTimeout(function(){...}, 時間 // 等待多久時間啟動 // 單位為 1 ms 毫秒 clearTimeout(timeout) ``` 投影幕的概念 - .slideDown - .slideUp - .append() - .prepend() - .prependTo() 放最前面 - .appendTo() 放最後面 ```javascript= $('.dots div:last-child').prependTo($('.dots')) 把最後一個div放進.dots這個div裡面的最前面 $('.dots').prepend($('.dots div:last-child')) 讓.dots這個div裡的最後一個div移到最前面 ``` [Math.floor 說明](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Math/floor) ## 你可能不需要 jQuery !!! - ==IE 已死 !!! Die!!! Die!!! Die!!!== - 純粹把 DOM API 包起來增加效能,沒有本質上的改變 - [查查看人家怎麼改](http://youmightnotneedjquery.com/) --- ## 題外話 * 西瓜不建議用 this ,因為在 JS 裡不能馬上分辨 this 是指哪個物件,同時環境越來越複雜的時候,會搞不清this在指誰 * 但建議要理解 this ,面試會問,而且若是接手到以前的專案也有機會碰到 * 清除瀏覽器快取(Cache),查看最真實正確的網站狀況 * 開發者工具 -> Network -> Disable cache 打勾 ![](https://i.imgur.com/yIqp4zG.png) * Vue.js 跟 React.js:JS框架,更好的模組化,處理各種行為 * html 文字:DOM 將他實體化放在瀏覽器的樣子 --- ## 下面是西瓜老師提供的範例 & Info ### Callback [MDN](https://developer.mozilla.org/zh-TW/docs/Glossary/Callback_function) ```javascript= function afterOneSecond(callback) { setTimeout(function() { callback(); }, 1000) } afterOneSecond(function() { console.log('callback called') }) ```