iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 4
0

今日主題是透過 TodoList 來學習

  • 原生 javascript 裡的 API
  • 讀 MDN 上的文件
  • 你的 this 是我的 that 還是窗戶

Todo List - codepen

第一段代碼

var myNodelist = document.getElementsByTagName("li");
var i;
for (i = 0; i < myNodelist.length; i++) {
  var span = document.createElement("SPAN");
  span.className = "close";
  var txt = document.createTextNode("x");
  span.innerHTML = 'x';
  myNodelist[i].appendChild(span);
}

Code註釋

  • 使用 document API 取得所有是 li 標籤的 HTMLCollection ,把它存放在 myNodelist 這個參數以便以後可以使用
  • forloop 裡面
    • 創一個 span 的節點像是這樣 x
    • 將這個 span 放到每個 myNodelist 的 NodeList

即時詞彙

getElementsByTagName

returns a collection of all elements in the document with the specified tag name, as a NodeList object

HTMLCollection

An HTMLCollection object is an array-like list (collection) of HTML elements.

NodeList

NodeList 物件是節點的集合,可藉由 Node.childNodes 屬性以及 document.querySelectorAll() 方法取得。

學到了什麼?

看到這裡有沒有很有趣,所有 HTML 上的標籤可以透過 javascript 來存取,document 上有很多的功能可以使用,在這個例子上我們就使用了 getElementsByTagName 這個 method,平常想知道有什麼功能的話可以直接看文件,或者是打開 inspector(在瀏覽器按右鍵選擇 檢查),然後在 console 的地方打 document 就會看到許多的功能了

(如果不知道我在說什麼可以 google 關鍵字 chrome 開發者工具,有很多教學!)

現在我們來試試把以下 code 貼到 console 上吧

document.getElementsByTagName('div');
HTMLCollection(1064) [...]

這樣子打出來會看到一個上是 Array 的物件叫做 HTMLCollection

咦!奇怪了為什麼又有一個 NodeList 的像是 Array 的物件呢?

HTMLCollection vs NodeList

其實這兩個差不多
HTMLCollection 多了把 element 上有 ID 的節點放到 HTMLCollection 物件中
試著把這個代碼貼到 console 中看看吧!

document.getElementsByTagName('div');
// HTMLCollection() [...] { some-id: div#some-id.xxx}
document.querySelectorAll()
// NodeList() [...] <- 只有 List 而已

HTMLCollection 官方文件說是 live 的,也就是說只要有 DOM 上有更新這個參數就會更新

來做個實驗吧

var blocks = document.getElementsByTagName('div');
console.log(blocks.length); // assume output 1
document.children[0].appendChild(document.createElement('div')) // 亂加個 div
console.log(blocks.length); // will output 2

而 NodeList 呢?
官方文件說大部分情況是 live 的(可以去官方看例子喔)
但有時候卻是 static,文件指出使用了 document.querySelectorAll 的時候會拿到一個 static 狀態的 NodeList

static 狀態就是參數不會被更新如果 DOM 被更新的時候

再來做個實驗吧!(把以下代碼貼到 console 上)

var blocks = document.querySelectorAll('div');
console.log(blocks.length); // assume output 1
document.children[0].appendChild(document.createElement('div')) // 亂加個 div
console.log(blocks.length); // will output 1

是不是很有趣呢!

回到我們的代碼你會發現這個 TodoList 為什麼是用 getElementsByTagName 而不是 querySelectorAll 是不是很明顯了呢!

因為 li 節點會被存在 myNodelist 中,因為是 live 的關係,當 addTodo 新增了新的 li 就不用擔心 myNodelist 沒被更新了

心得:

天色已晚,今天就到這吧!其實我今天才發現這個差別,以前也沒有注意到這件事情,算是認真研究做學問,今天長知識了!


上一篇
Day03 - 瀏覽器如何解讀網頁
下一篇
Day05 - TodoList js - II
系列文
認真學前端開發 - 以 TodoList 為例30

尚未有邦友留言

立即登入留言