今日主題是透過 TodoList 來學習
this
是我的 that
還是窗戶Todo List - codepen
// Click on a close button to hide the current list item
var close = document.getElementsByClassName("close");
var i;
for (i = 0; i < close.length; i++) {
close[i].onclick = function() {
var div = this.parentElement;
div.style.display = "none";
}
}
// Add a "checked" symbol when clicking on a list item
var list = document.querySelector('ul');
list.addEventListener('click', function(ev) {
if (ev.target.tagName === 'LI') {
ev.target.classList.toggle('checked');
}
}, false);
<span class="close">x<span>
getElementsByClassName
取得符合 class 等於 close 的 HTMLCollection
close element
都給個 onclick
的 anonymous function
function
出現了 this
,而這個 this
居然是 close[i]
那一個 node
這邊稍作一點說明在 javascript 中 this
通常指的是呼叫該 method
的人,而非該 method
的物件本身,例如當 close[0] 被點擊了,底層的十之八九是 close[0].onclick(e)
來執行這個 function
那這個 this
就會指向 close[0]
,所以通常給 Node event function 會利用這個特性直接使用 this
來操作該節點
如果試試看改成這樣會發生什麼事呢?
close[i].onclick = function() {
var div = this.parentElement;
div.style.display = "none";
}
var myImmediateEvent = close[i].close;
myImmediateEvent();
會發現 this
壞掉了,而 console 的 error 說的是 undefined
沒有 style
的 property
原因是呼叫 myImmediateEvent
沒有主人,順其自然就是最外層的呼叫 myImmediateEvent 了
而 window 上的 property 沒有 parentElement
這個 property 所以頁面就壞掉啦~
假設 window
有這個 property
其實更危險,因為可能改動到其他 module 的功能。
this 的原理可以詳讀
// Create a new list item when clicking on the "Add" button
function addTodo() {
var li = document.createElement("li");
var inputValue = document.getElementById("todo-input").value;
var t = document.createTextNode(inputValue);
li.appendChild(t);
if (inputValue === '') {
alert("請輸入待辦事項");
} else {
document.getElementById("todo-list").appendChild(li);
}
document.getElementById("todo-input").value = "";
var span = document.createElement("SPAN");
var txt = document.createTextNode("x");
span.className = "close";
span.appendChild(txt);
li.appendChild(span);
for (i = 0; i < close.length; i++) {
close[i].onclick = function() {
var div = this.parentElement;
div.style.display = "none";
}
}
}
最後是這一段 addTodo
function 的代碼
這邊的流程就是
<li></li>
的 element然後加到 div#todo-list 後面<span>x</span>
加到 #1 創建的 li
之後close
這個 HTMLCollection 的參數設定 onclick method如果有看昨天的說明就會了解 live
的 HTMLCollection 原理,所以這個 addTodo function 才能這樣子跑
有沒有覺得很奇怪,第一段代碼的地方 <span>x</span>
這個節點是用 span.innerHTML="x" 加上去的,但這段代碼的 span
上的 x
和 li
的文字是用 createTextNode
我覺得這段 javascript 很容易踩到雷,所以要小心
同樣先看 MDN 好像沒有特別講
不過意思是說你輸入的文字都會幫你加到節點裡
而 innerHTML 會把輸入的文字變成 HTML ,然後就有可能被使用者用文字攻擊囉~
試試這段代碼
var child = document.createElement('div')
child.innerHTML = '<div></div>'
console.log(child)
所以記得要小心使用 innerHTML
到目前為只有看到三種 click event 的寫法,想必大家也很好奇其中的奧妙,明天來看看 event 的部分吧!