控制判斷
if
單條件
if (判斷式) { |
當 ()
內的判斷式成立時,便會執行 {}
內的陳述式 1 ,否則會執行 else{}
內的陳述式 2。
多條件
if (判斷式A) { 陳述式 1 } |
- 當
(判斷式A)
成立時,便會執行{陳述式 1}
。 - 當
(判斷式A)
不成立但(判斷式B)
成立時,便執行{陳述式 2}
。 - 當所有判斷式皆不成立,便執行
else{}
內的陳述式 3。
- 可設立多於1組以上的條件。
switch
switch (expression) { |
- 設定一個表達式
switch()
,且包含一個條件。 - case: 比對 case 的 value,當符合就會執行與此條件相關的陳述式。
- default: 當所有條件皆未成立時,便會執行 default,default 不一定要放在最後位置。
- break: 阻止已完成的區塊繼續執行。
迴圈
迴圈提供一個快速又簡潔的方法來重複地做某件事。
for 迴圈
for ( [初始表達式] ; [條件式] ; [遞增表達式]) { |
- 迴圈內須以
;
區分各個條件。
- 初始表達式 - 代表初始狀態,可為 1個 或 多個,這個表達式也能用來宣告變數。
- 條件式 - 如果評估出的值為true,便會執行陳述式的內容。但如果評估出的值為false,這個for迴圈便會中止。
- 遞增表達式 - 會在陳述式每次被執行後執行。
for array
for ( let i = 0 ; i < array.lengh ; i++ ) { |
for if
for ( let i = 0 ; i < array.lengh ; i++ ) { |
for break
for ( let i = 0 ; i < array.lengh ; i++ ) { |
DOM
DOM( Document Object Model )中文為 文件物件模型。
在DOM的標準下,一份文件中所有的標籤定義,包括文字,都是一個物件,這些物件以文件定義的結構,形成了一個樹狀結構。
樹狀結構:
- 根(root):結構的開端,或稱為根結點。
- 節點(Node):樹狀結構中的基本單位。
- 分支(branch):節點之間的連結,節點與分支形成樹狀。
- 子節點(child):根節點之外的節點。
- 葉節點(Leaf):沒有連結到其他子節點的節點。
DOM解析
<html> |
graph TD A(document) --> B[Root element
<html>] B --> C[Element:
<Head>] C --> D[Element:
<Title>] D --> E[Text:
'首頁'] B --> F[Element:
<Body>] F --> G[Element:
<H1>] G --> H[Text:
'Hello!World!'] F --> I[Element:
<a>] I --> J[Text:
'學習筆記'] I --> L[Attribute:
'href'] style A fill:#27ae60,stroke-width:0
- document:document代表整個文件,而不代表html節點。
- Element:是所有標籤(也是節點),包含、等等各種 HTML Tag。
- Text:指被標籤包起來的文字元素(也是節點)。
- Attribute:指各個標籤內的相關屬性。
為何需要DOM
With the object model, JavaScript gets all the power it needs to create dynamic HTML:
- JavaScript can change all the HTML elements in the page
- JavaScript can change all the HTML attributes in the page
- JavaScript can change all the CSS styles in the page
- JavaScript can remove existing HTML elements and attributes
- JavaScript can add new HTML elements and attributes
- JavaScript can react to all existing HTML events in the page
- JavaScript can create new HTML events in the page
DOM 是 W3C (World Wide Web Consortium) 所制訂的標準。
W3C聯合各瀏覽器廠商制訂了標準物件模型,讓瀏覽器可以按照這些標準去設計,DOM 就是其中的一個定義。
DOM標準分成了3個部分。
- Core DOM - standard model for all document types
- XML DOM - standard model for XML documents
- HTML DOM - standard model for HTML documents
圖片來源:http://www.w3.org/TR/DOM-Level-3-Core/introduction.html
HTML DOM
- The HTML elements as objects
- The properties of all HTML elements
- The methods to access all HTML elements
- The events for all HTML elements
換句話說,HTML DOM 是一個該如何取得、改變、新增、刪除 HTML元素的標準。
HTML DOM 操作
document.getElementById(id)
- 找尋 DOM 中符合此 id 名稱的元素,並回傳相對應的 element。
document.getElementsByTagName(name)
- 找尋 DOM 中符合此 tag 名稱的所有元素,並回傳相對應的 element 集合,集合為
HTMLCollection
。
document.getElementsByClassName(name)
- 找尋 DOM 中符合此 class 名稱的所有元素,並回傳相對應的 element 集合,集合為
HTMLCollection
。
document.querySelector(selector)
- 利用 selector 來找尋 DOM 中的元素,並回傳相對應的第一個 element。
document.querySelectorAll(selector)
- 利用 selector 來找尋 DOM 中的所有元素,並回傳相對應的第一個 element ,集合為
NodeList
。
HTMLCollection 以及 NodeList 的差異
HTMLCollection
NodeList
HTMLCollection
為 HTML element 的集合。NodeList
為 Node 的集合。HTMLCollection
&NodeList
幾乎相同。- 兩者皆為類陣列,並繼承於
objects
。 - 兩者皆有
length
屬性。 HTMLCollection
有namedItem
(根據 ID & Name 篩選元素)的方法。NodeList
則有entries
,forEach
,item
,keys
,values
5個方法。
增加節點
innerHTML
- 透過 innerHTML 可以取得或設定 HTML Code 中的元素,也可以單純的將字串寫入 HTML Code 的某一個部分。 盡量避免使用。
textContent
- 表示節點或其後代的文字內容。
document.createElement(tagName)
- 可以依指定的標籤名稱(
tagName
)建立 HTML 元素,或是在未定義標籤名稱下建立一個 HTMLUnknownElement。
document.createTextNode()
- 用來建立文字節點的方法,直接加入字串即可。
document.createDocumentFragment()
- 它是一種沒有父層節點的「最小化文件物件」。 可以把它看作是一個輕量化的 Document,用如同標準文件一般的方式來保存「片段的文件結構」。
- 因為
createDocumentFragment()
是存在記憶體中,增加子元素並不會導致網頁 reflow (重新計算元素的位置和幾何)。因此採用createDocumentFragment()
通常會有比較好的效能表現 (better performance)。
Element.insertAdjacentHTML()
- 把傳入的字串解析成 HTML 或 XML,並把該節點插入到 DOM 樹指定的位置。它不會重新解析被使用的元素,因此他不會破壞該元素裡面原有的元素。這避免了序列化的複雜步驟,使得它比直接操作
innerHTML
快上許多。
position
相對於元素的位置,並且必須是以下字符串之一:
'beforebegin'
: 在 element 之前。'afterbegin'
: 在 element 裡面,第一個子元素之前。'beforeend'
: 在 element 裡面,最後一個子元素之後。'afterend'
: 在 element 之後。
text
text
是即將被解析並插入到 DOM 樹裡的字串。
<!-- beforebegin --> |
Note: beforebegin
和 afterend
只在該節點位於 DOM 樹內、並且有母元素時有效。
節點的修改與刪除
NODE.appendChild(childNode)
- 可以將指定的
childNode
節點,加入到Node
父容器節點的末端。
NODE.insertBefore(newNode, refNode)
- 將新節點
newNode
插入至指定的refNode
節點的前面。
NODE.replaceChild(newChildNode, oldChildNode)
- 將原本的
oldChildNode
替換成指定的newChildNode
。
NODE.removeChild(childNode)
- 將指定的
childNode
子節點移除。
event 事件
target.addEventListener(type, listener[, options]); |
- type
- 表示所監聽的 event type 名稱之字串。
- listener
- 當監聽的事件觸發時指定執行的函式,也稱為 callback function 。
- options
-
可選。預設值為:false。
- false:Event Bubble - 事件冒泡:從指定元素往外層尋找。
- true:Event Capture - 事件捕捉:從最外層向內層尋找指定元素。
capturing & bubbling 的差異
這其實是在講 DOM 裡面事件傳遞的順序。
假如在兩個元素上面都加了eventListener
,哪一個會先執行?此時,知道事件的執行順序就很重要。
- Event bubbling - 事件冒泡
- Event capturing - 事件捕捉
事件的三個 Phase
- 當點下
td
時,這一個點擊的事件會先從window
開始往下傳遞,直到傳到td
為止,此階段稱為CAPTURING_PHASE
,捕獲階段。 - 接著事件傳遞到
td
本身,此階段稱為AT_TARGET
。 - 最後事件會從
td
往上傳遞回window
,此階段稱為BUBBLING_PHASE
,冒泡階段。
通常在呼叫 callback function 的時候,會傳進一個值 event
通常會縮寫 e
,e
裡面就蘊含了許多這次觸發事件的相關參數。
其中一個參數 eventPhase
,會回傳一個數字,表示這個事件在哪一個 Phase 觸發。
eventPhase | Number |
---|---|
CAPTURING_PHASE | 1 |
AT_TARGET | 2 |
BUBBLING_PHASE | 3 |
取消事件傳遞
event.stopPropagation(); |
stopPropagation()
方法可阻止當前事件繼續進行捕捉(capturing)及冒泡(bubbling)階段的傳遞。
event.stopImmediatePropagation(); |
stopImmediatePropagation()
方法除了停止事件繼續捕捉或冒泡傳遞外,也阻止事件被傳入同元素中註冊的其它相同事件類型之監聽器。
取消預設行為
event.preventDefault(); |
preventDefault()
方法可取消事件的預設行為。但不會影響事件的傳遞,事件仍會繼續傳遞。
目前所在元素位置
event.target(); |
event.target
屬性永遠指向最初觸發事件的 DOM 物件。
常見的 event type
- click - 點擊滑鼠左鍵時觸發。
- change - 表單內容更動內容時觸發。
- keyCode - 按下指定按鍵時觸發。
- focus - 進入焦點時進行事件觸發。
- blur - 離開焦點時進行事件觸發。
- mousemove - 當滑鼠滑入指定內容時觸發。
網頁座標
e
裡面蘊含了許多觸發事件的相關參數,包括與網頁座標的相關參數。
e.screenX
、e.screenY
- 抓取整個螢幕的大小。e.pageX
、e.pageY
- 抓取整個網頁的大小。e.clientX
、e.clientY
- 抓取瀏覽器的大小。
實際應用
event delegation(事件代理)
利用事件捕獲跟冒泡的機制,將多個
addEventListener()
綁定在同一個父節點。
如此一來當新增或是刪除一個元素的時候,不用去處理跟那個元素相關的 listener,因為 listener 是放在父節點身上。
而此透過父節點 listener 來處理子節點的事件,就稱做事件代理。
使用時機:
- 過多重複的監聽器 — 需要掛載非常多個重複的事件
- 掛載、移除事件是有成本的 — removeEventListener 超級麻煩
原理:
- 事件的冒泡機制 — 把子節點們的事件統一處理
- 事件的 e.target 屬性 — 辨別事件的位置
流程:
- 新增監聽父節點。
- 加入判斷,排除父節點。
e.target.classList.contains('搜尋的子節點')
,如果有回傳 true沒有則回傳 false。 MDNe.target.nodeName === '要匹配的子節點'
。 MDN
<div class="outer"><a href="#" class="add">Add</a></div> |
data-* 資料屬性
- HTML5 內新增的一項自訂 data 屬性的屬性。
- 它能令 HTML 與其 DOM 擁有給腳本用的交換資訊。
- 可以於 HTML 標籤內添加任意
data-*
的屬性,其中的*
就是一個可以自定義的名稱,而此屬性並不會渲染於網頁上,但可以透過 CSS & JS 讀寫以及操作此屬性。*
只接受字母、數字還有以下的符號: dash (-
), 點 (.
), 冒號 (:
), 底線(_
) – 但不包含任何ASCII 大寫字母(A 到 Z)。- 用JavaScript裡使用data-*屬性名時,要把名稱轉變成駝峰式命名(Camel-Case),且不含dash、點等上述所提的符號。
<ul id="menu" data-toggle="collapse"> |
取值
CSS
搭配使用 CSS 中的屬性選取器可以取得或選取 data-*attribute
#menu[data-toggle="collapse"] { |
JS
當要取得 data-* attribute 的屬性值時,我們可以利用 JavaScript 中的 dataset
物件。
如果包含dash、點等符號,要把名稱轉變成駝峰式命名(Camel-Case)。
let menu = document.querySelector('#menu'); |
賦值
let menu = document.querySelector('#menu'); |
與 Array 搭配使用
- 從 webStorsge 取值,設定變數為 data ,如果無值則建立一個空陣列。
let data = JSON.parse(sessionStorage.getItem('toDoList')) || [];
- 新增資料,將
input
內的值帶入物件並psuh
進data
陣列內。
再將data
陣列更新進 webStorsge 內。function addDate(e) {
let toDoItem = document.querySelector('.text').value;
if ( toDoItem === '' ) {return};
document.querySelector('.text').value = '';
let toDo = { content: toDoItem };
data.push(toDo);
sessionStorage.setItem('toDoList', JSON.stringify(data));
updateList(data);
} - 更新資料,並將內容插入至 list 內。
send.addEventListener('click', addDate);
function updateList(item) {
let str = '';
for (let i = 0; i < item.length; i++) {
str += `<li><a href="#" data-index="${i}">刪除</a> <span>${data[i].content}</span></li>`;
}
list.innerHTML = str;
} - 移除資料,使用事件代理,父節點 list 做為監聽對象,監聽子節點的 A 標籤,移除後並重新更新資料。
list.addEventListener('click', delToDoItem)
function delToDoItem(e) {
e.preventDefault();
if (e.target.nodeName !== 'A') {return}; // nodeName 不等於 'A',不動作。
let num = e.target.dataset.index;
data.splice(num, 1);
console.log(data);
sessionStorage.setItem('toDoList', JSON.stringify(data));
updateList(data);
}
web storage
- HTML5 新加入的 Web Storage 是一種可讓網頁將資料儲存於本地端的技術,其作用如同 cookie。
- 儲存於 Web Storage 中的資料,是以 key-value pair 的形式保存。
- 解決cookie存儲空間不足的問題(cookie中每條cookie的存儲空間為4k),localStorage中一般瀏覽器支持的是5M大小。
- Web Storage 分為兩種:
localStorage
和sessionStorage
。
基本操作
setItem()
- 將資料存進 localStorage 內。SyntaxlocalStorage.setItem($key, $value);
sessionStorage.setItem($key, $value);getItem()
- 將資料從 localStorage 內取出。SyntaxlocalStorage.getItem($key);
sessionStorage.getItem($key);removeItem(key)
- 清除某一筆資料SyntaxlocalStorage.removeItem($key)
clear()
- 清除全部資料SyntaxlocalStorage.clear()
資料儲存的格式
localStroage key
跟 value
只能保存字串的資料,存取 JSON 格式要先經過轉換。
- 將 array 轉為 string Syntax
JSON.stringify(array)
- 將 string 轉為 array Syntax
JSON.parse(string)
BOM
BOM (Browser Object Model,瀏覽器物件模型),是瀏覽器所有功能的核心。
BOM 的核心其實是 window 物件。而 window 物件提供的屬性主要有 document、location、navigator、screen、history 以及 frames。
在瀏覽器裡的 window 物件扮演著兩種角色:
- ECMAScript 標準裡的「全域物件」 (Global Object)
- JavaScript 用來與瀏覽器溝通的窗口
常用語法
- 回到上一頁
window.history.back()
- 到下一頁
window.history.forward()
- 列印
window.print()
- local資訊
window.location()
- 目前的URL(currentURL)
const currentURL = () => window.location.href;
- 移動到其他網頁
window.open(url)
- 瀏覽器視窗內高度
window.innerHeight;
- 瀏覽器視窗內寬度
window.innerWidth;
- 瀏覽器高度
window.outerHeight;
- 當瀏覽器高度有變化時觸發function
window.onresize = function() {};