# JavaScript DOM Crash Course --- tags: Javascript relate --- ###### tags: `Javascript` # JavaScript DOM Crash Course Part - 1 ## DOM簡介 * Document Object Model * 由瀏覽器建構的樹的節點(nodes)意味著每個節點都有各自的property跟方法可以運用 * JS可以被用來讀寫以及操作DOM * 物件導向的呈現方式 ![](https://i.imgur.com/Ph2hcZr.png) ## 作者使用下方這個Item Lister來做為範例教學DOM的操作 ![](https://i.imgur.com/jOdC6jX.png) 這邊的HTML可直接貼上編輯器就可以直接使用 ```htmlembedded= <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous"> <title>Item Lister</title> </head> <body> <header id="main-header" class="bg-success text-white p-4 mb-3"> <div class="container"> <div class="row"> <div class="col-md-6"> <h1 id="header-title">Item Lister</h1> </div> <div class="col-md-6 align-self-center"> <input type="text" class="form-control" id="filter" placeholder="Search Items..."> </div> </div> </div> </header> <div class="container"> <div id="main" class="card card-body"> <h2 class="title">Add Items</h2> <form id="addForm" class="form-inline mb-3"> <input type="text" class="form-control mr-2" id="item"> <input type="submit" class="btn btn-dark" value="Submit"> </form> <h2 class="title">Items</h2> <ul id="items" class="list-group"> <li class="list-group-item">Item 1 <button class="btn btn-danger btn-sm float-right delete">X</button></li> <li class="list-group-item">Item 2 <button class="btn btn-danger btn-sm float-right delete">X</button></li> <li class="list-group-item">Item 3 <button class="btn btn-danger btn-sm float-right delete">X</button></li> <li class="list-group-item">Item 4 <button class="btn btn-danger btn-sm float-right delete">X</button></li> </ul> </div> </div> <script src="dom.js"></script> </body> </html> ``` ## 檢視 document 的物件 `console.dir(document);` 這邊會在開發者工具印出非常多的properties以及methods不過作者會挑幾個比較重要的說明 ```javascript= //要使用document 的方法(.) console.log(document.方法) ``` ## document常用方法介紹: ```javascript= console.log(document.domain);//127.0.0.1 - 可以查看網域(domain) console.log(document.URL);//http://127.0.0.1:5500/index.html - 查看網址 console.log(document.title);//Item Lister - 查看title console.log(document.doctype);//<!DOCTYPE html> - 查看檔案類型 console.log(document.body);// 可以在console查看body的元素 console.log(document.head);// 可以在console查看head的元素 console.log(document.forms);// 可以在console查看所有form的元素以及他的方法 console.log(document.links);//可以在console查看link的元素 console.log(document.images);//可以在console查看images的元素 ``` 也可以直接修改title ```javascript= document.title = '123'; ``` ![](https://i.imgur.com/JmgXdYH.png) 下方這個方法會給我們一個HTMLCollection包含了所有的HTML元素以及很多可以使用的方法(methods) ```javascript= console.log(document.all); ``` ![](https://i.imgur.com/WEQB3tG.png) 如果我們想要擷取其中的內容: 可以這樣使用使用他的檢索號碼就可以抓取內容 ```javascript= console.log(document.all[1]); ``` ![](https://i.imgur.com/ya1zcgB.png) ## selectors(選取器)介紹 用來抓取元素 ### getElementById 輸入要選取的 id 就可以抓取選取的元素 ```javascript= console.log(document.getElementById('header-title')); ``` ![](https://i.imgur.com/wljNYqG.png) 也可以把抓取的內容指派給變數使用,這樣在呼叫的時候就只要呼叫變數就好不用整串都打 ```javascript= var headerTitle = document.getElementById('header-title'); console.log(headerTitle); ``` ### textContent & innerText 這兩個方法可以針對選取的元素修改其文字內容 它們的不同之處在於: textContent不會看到CSS修改的部分 innerText會看到CSS修改的部分 ```javascript= // 把內文從item Lister改成 Hello 跟 Goodbye headerTitle.textContent = 'Hello'; headerTitle.innerText = 'Goobye'; ``` ![](https://i.imgur.com/c7LjSGb.png) ### innerHTML 用來加入新的HTML tag來加入舊的tag並不是直接取代 ```javascript= headerTitle.innerHTML = '<h3>HEllo</h3>'; ``` 原本的tag還保留 ![](https://i.imgur.com/OxSt9Ah.png) 使用過後修改成`'<h3>HEllo</h3>'` ![](https://i.imgur.com/TXmXDYA.png) ### style 修飾被抓取元素的CSS 選擇要使用的CSS屬性的部分不能照原本CSS格式的寫法要改成JS的寫法(camel型態的字首英文大小) ```javascript= header.style.borderBottom = 'solid 3px #000'; ``` 多加了底線上去 ![](https://i.imgur.com/TkBcCTz.png) ### getElementByClassName 一樣會用HTMLCollection包裝好內容印出給我們 ```javascript= var items = document.getElementsByClassName('list-group-item'); console.log(items); ``` 印出結果: ![](https://i.imgur.com/Ah4tqy2.png) 這邊我們可以使用`console.log(items[1])`擷取內容 ```javascript= console.log(items[1]); ``` ![](https://i.imgur.com/xnpMmf1.png) 並且修改選取的元素文字內容 ```javascript= items[1].textContent = 'hello2'; ``` ![](https://i.imgur.com/XdOdEVS.png) 也可以更改他的CSS ```javascript= items[1].style.fontWeight = 'bold';// 字體變粗體 items[1].style.backgroundColor = 'yellow';//加上背景色黃色 ``` ![](https://i.imgur.com/11GKWCT.png) CSS修飾全部選取的內容 使用下面這串是會報錯的 因為它是一個HTMLCollection沒有辦法直接使用方法,所以必須使用迴圈一個一個印出去使用方法 ```javascript= //錯誤寫法會報錯 items.style.backgroundColor = '#f4f4f4'; ``` ![](https://i.imgur.com/uBADpUJ.png) 正確解法: ```javascript= for (i = 0; i < items.length; i++) { items[i].style.backgroundColor = 'red'; } ``` 這樣就可以全部都上色瞜! ![](https://i.imgur.com/Sn8L3DK.png) ### getElementByTagName 這邊會的到跟上面getElementByClassName一樣的結果,因為選取的是一樣的元素 ```javascript= var li = document.getElementsByTagName('li'); console.log(li); console.log(li[1]); li[1].textContent = 'hello2'; li[1].style.fontWeight = 'bold'; li[1].style.backgroundColor = 'yellow'; for (i = 0; i < li.length; i++) { li[i].style.backgroundColor = 'red'; } ``` 這邊的例子可以看到CSS的修飾的部分一樣會吃到item 5因為DOM Seletor這邊抓取的是tag`<li>` 如果這邊處理的在getElementByClassName的話就不會出現紅色的背景因為item 5 沒有class ![](https://i.imgur.com/aWdYiiV.png) ![](https://i.imgur.com/Cy5EfQV.png) ### querySelector 可以選取任何在HTML上面的元素以及class,id都可以,並做修改跟操作 ```javascript= var header = document.querySelector('#main-header'); header.style.borderBottom = 'solid 4px red'//增加底線 var input = document.querySelector('input'); input.value = 'Hello World';//改變input的value var submit = document.querySelector('input[type ="submit"]'); submit.value = "Send";// 選取type的作法要加上[] 修改按鈕的value改成Send ``` ![](https://i.imgur.com/10uRKIf.png) ![](https://i.imgur.com/cMcCPLm.png) ### querySelector - CSS偽類的使用 * 如果沒有作處理就影響第一個 * last-child * nth-child(i) ```javascript= var item = document.querySelector('.list-group-item'); item.style.color = 'red'//如果選取對象是複數並且沒有告訴它影響哪一個的話會影響第一個 var lastItem = document.querySelector('.list-group-item:last-child');//偽類( Pseudo-classes ) lastItem.style.color = 'green'; var secondItem = document.querySelector('.list-group-item:nth-child(2)'); secondItem.style.color = 'coral'; ``` ![](https://i.imgur.com/2rVT0TF.png) ### querySelectorAll 可以抓取所有選取的內容HTML tags, id, class並且產一個Nodelist它是可以使用array function的!! ```javascript= var titles = document.querySelectorAll('.title'); console.log(titles); ``` ![](https://i.imgur.com/GQselnn.png) ```javascript= titles[0].textContent = 'Hello';// 當然它也可以這樣選取索引號碼後做修改 ``` ![](https://i.imgur.com/zqPPvpV.png) ### 選取基數元素上色(進階處理): 一樣使用偽類 `nth-child(i)`裝飾元素 ```javascript= var odd = document.querySelectorAll('li:nth-child(odd)'); for (var i = 0; i < odd.length; i++) { odd[i].style.backgroundColor = 'green' } ``` ![](https://i.imgur.com/JZHvsxu.png) # JavaScript DOM Crash Course Part - 2 ## DOM的移動(traversing the DOM) ### parentNode 抓取目前物件的parent也就是外層的物件 ```javascript= var itemList = document.querySelector('#items'); //parentNode console.log(itemList.parentNode); itemList.parentNode.style.backgroundColor = 'red' ``` 這邊抓取的是item的id它的parentNode是外層的div ![](https://i.imgur.com/SMvczhU.png) 然後我們對它修飾CSS ![](https://i.imgur.com/EAN1S7H.png) 並且parentNode的使用是可以疊起來的 ```javascript= console.log(itemList.parentNode.parentNode.parentNode); ``` 會找的外層的外層的外層找到body去了 ![](https://i.imgur.com/iaubbVR.png) #### parentElement 幾乎跟parentNode的功能一樣是可以互相替換的 ```javascript= console.log(itemList.parentElement); itemList.parentElement.style.backgroundColor = 'red' console.log(itemList.parentElement.parentElement.parentElement); ``` ### childNodes(不推薦使用) ```javascript= console.log(itemList.childNodes); ``` 中間包含的text是指斷行 ![](https://i.imgur.com/FHpM5v5.png) 所以當你把它們全都黏在一起時text就會消失 ![](https://i.imgur.com/bPek77e.png) 因為中間的斷行消失 ![](https://i.imgur.com/Uu1IXD4.png) ### children(推薦使用) * 功能跟childNodes一樣不過不會顯示出進去斷行 * 並且呈現方式變成HTMLCollection ```javascript= console.log(itemList.children); ``` ![](https://i.imgur.com/ir7eVwY.png) 如果想要擷取裡面的內容: ```javascript= console.log(itemList.children[1]); ``` ![](https://i.imgur.com/05rhgYt.png) 要修改選取元素的CSS: ```javascript= itemList.children[1].style.backgroundColor = 'yellow'; ``` 修改其CSS為背景色黃色 ![](https://i.imgur.com/oTxM0NZ.png) ### Firstchild(不推薦使用) 會印出第一個元素,但是這個方法一樣會印出斷行所以基本上會印出text ```javascript= console.log(itemList.firstChild); ``` ![](https://i.imgur.com/PVAXlcm.png) ### FirstElementChild(推薦使用) 這個就不會印出text搂 ```javascript= console.log(itemList.firstElementChild); ``` ![](https://i.imgur.com/Rh8e3pJ.png) 當然也可以針對它選取的元素做文字修改 ```javascript= itemList.firstElementChild.textContent = 'hello 1'; ``` ![](https://i.imgur.com/bzI0VjC.png) ### lastchild(不推薦使用) 跟firstchild相反印出最後一個元素但是缺點是會印出斷行印出text ```javascript= console.log(itemList.firstChild); ``` ### LastElementChild(推薦使用) 不會印出斷行text以及也可以進行文字修改操作 ```javascript= console.log(itemList.lastElementChild); itemList.lastElementChild.textContent = 'hello 4'; ``` ![](https://i.imgur.com/X4jRXQF.png) ### nextSibling(不推薦使用) 會抓取sibling 下一個位於同一層的元素,一樣的缺點會抓取斷行出現text ```javascript= console.log(itemList.nextSibling); ``` ![](https://i.imgur.com/mAxqpVQ.png) ### nextElementSibling(推薦使用) 不會出現斷行正常抓取下一個同層元素 ```javascript= console.log(itemList.nextElementSibling); ``` ![](https://i.imgur.com/9tOolhe.png) ### previousSibling(不推薦使用) 會抓取前一個位於同一層的元素 ,一樣的缺點會抓取斷行出現text ```javascript= console.log(itemList.previousSibling); ``` ### previousElemntSibling(推薦使用) 不會出現斷行正常抓取上一個同層元素 並且可以進行操作 ```javascript= console.log(itemList.previousElementSibling); itemList.previousElementSibling.style.color = 'green'; ``` ![](https://i.imgur.com/DRQYoAD.png) ### createElement 創造新的元素 ```javascript= var newDiv = document.createElement('div'); //增加class給div newDiv.className = 'hello' //增加id給div newDiv.id = 'hello1'; //增加attribute給div newDiv.setAttribute('title', 'hello Div'); //創造文字並指派給變數 var newDivText = document.createTextNode('Hello World'); //把文字加入div newDiv.appendChild(newDivText); console.log(newDiv); ``` 印出的結果 ![](https://i.imgur.com/pZS4l73.png) 把創造出來的div放進去專案中 ```javascript= //抓取想要放的位置 var container = document.querySelector('header .container'); var h1 = document.querySelector('header h1'); container.insertBefore(newDiv, h1);//使用方法插入newDiv ``` 印出結果 ![](https://i.imgur.com/KurzuOc.png) 修改newDiv 的CSS ```javascript= newDiv.style.fontSize = '30px'; ``` ![](https://i.imgur.com/2az5Uqi.png) # JavaScript DOM Crash Course Part - 3 這個部分的主題會環繞著事件(event) ## 事件監聽 (addEventListener) 新增一個按鍵等下作範例使用 ![](https://i.imgur.com/bLfJ37T.png) 我們可以對這個案件做事件監聽,並且在事件'click'發生的時候跑buttonClick這個function會印出'Button clicked'字樣 ```javascript= var button = document.getElementById('button').addEventListener('click', buttonClick); function buttonClick() { console.log('Button clicked'); } ``` ![](https://i.imgur.com/RZTW93z.png) funciton內部的功能也可以改成改寫header-title的文字: ```javascript= var button = document.getElementById('button').addEventListener('click', buttonClick); function buttonClick() { //console.log('Button clicked'); document.getElementById('header-title').textContent = 'change'; document.querySelector('#main').style.backgroundColor = 'red'; } ``` 點擊Click Here後Title的文字會變成change並且背景色改變為紅色 ![](https://i.imgur.com/FuNkv2p.png) ### 印出事件本身 會出現很多事件本身可以使用的方法(properties)例如 滑鼠位置 className altkey等等 ```javascript= var button = document.getElementById('button').addEventListener('click', buttonClick); function buttonClick(e) { console.log(e); } ``` 只擷取一部份 ![](https://i.imgur.com/3bihVBZ.png) ### properties使用方式介紹跟結果: 這邊列出的properties都可以在上面印出來的MouseEvent裡面找到 ```javascript= var button = document.getElementById('button').addEventListener('click', buttonClick); function buttonClick(e) { console.log(e.target);// 印出觸發事件本身的元素 console.log(e.target.id);// 印出觸發事件本身的元素的id console.log(e.target.className);//印出觸發事件本身的元素的className console.log(e.target.classList);// 印出觸發事件本身的元素classList 使用DOMTokenList console.log(e.type);//印出觸發事件本身的type是甚麼 //也可以這樣操作把取得的id文字加入欄位中用文字串接的方式 var output = document.getElementById('output123'); output.innerHTML = '<h3>'+e.target.id+'</h3>'; } ``` 印出的結果 ![](https://i.imgur.com/4MgIsuz.png) 把取得的id文字加入欄位中用文字串接的方式 ![](https://i.imgur.com/hwflr7y.png) ### 滑鼠位置擷取 * clientX,Y 滑鼠在瀏覽器上的位置 * offsetX,Y 滑鼠在物件元素上面的位置 ```javascript= function buttonClick(e) { console.log(e.clientX); console.log(e.clientY); console.log(e.offsetX); console.log(e.offsetY); } ``` 當點擊Click Here之後會印出它們的位置: ![](https://i.imgur.com/w9it4nW.png) ### 判斷是否按住該按鍵進而可以做不同的功能 當按住該按鍵的時候會顯示true放開則顯示false,可以用做if判斷式來做不同的功能 如: 當按住alt時,顯示XXX之類的功能 * altKey * ctrlKey * shiftKey ```javascript= function buttonClick(e) { console.log(e.altKey); console.log(e.ctrlKey); console.log(e.shiftKey); } ``` ### 滑鼠事件簡介+一個小練習 * click * dblclick * mousedown * mouseup ```javascript= var button = document.getElementById('button') button.addEventListener('click', runEvent);//單點擊啟動事件 button.addEventListener('dblclick', runEvent);//雙點擊啟動事件 button.addEventListener('mousedown', runEvent);//按下去瞬間就啟動事件 button.addEventListener('mouseup', runEvent);//滑鼠放開瞬間就啟動事件 function runEvent(e) { console.log('Event type:'+e.type); } ``` 印出的類型: ![](https://i.imgur.com/rc09izl.png) #### 為了展示mouseenter event創造一個新的黃色div ![](https://i.imgur.com/2UWxHep.png) ##### mouseenter & mouseleave / mouseover & mouseout 當滑鼠進出的瞬間就會印出方法runEvent 他們的功能很像不過有差異: mouseenter & mouseleave只會在進出物件的時候會觸發 mouseover & mouseout 則是除了進出之外碰到內部的子元素(這邊的例子是HELLO)都會觸發 ```javascript= var box = document.getElementById('box'); box.addEventListener('mouseenter', runEvent); box.addEventListener('mouseleave', runEvent); box.addEventListener('mouseover', runEvent); box.addEventListener('mouseout', runEvent); function runEvent(e) { console.log('Event type:'+e.type); } ``` ![](https://i.imgur.com/AzlLPxM.png) #### mousemove 當滑鼠在物件內移動時觸發事件 ```javascript= var button = document.getElementById('button'); var box = document.getElementById('box'); box.addEventListener('mousemove', runEvent); function runEvent(e) { console.log('Event type:'+e.type); } ``` 通常觸發次數很高 ![](https://i.imgur.com/rzgJcmH.png) #### 加上滑鼠的位置呈現在頁面上 先抓取id後並指派給output變數,抓取box id指派給box變數, 並把box加入事件監聽使用mousemove並印出它的value呈現在頁面上 這個output的位置 ![](https://i.imgur.com/3iuiubk.png) ```javascript= var box = document.getElementById('box'); var output = document.getElementById('output123'); box.addEventListener('mousemove', runEvent); function runEvent(e) { output.innerHTML = '<h3>MouseX: '+e.offsetX+'<h/3><h3>MouseY:'+e.offsetY+'</h/3>';//這邊修改它的HTML內容加入新的<h3>tag以及滑鼠位置 } ``` 印出來的結果位置: ![](https://i.imgur.com/Uw02oHL.png) #### 下一步我們要做的事情是把抓取到的滑鼠座標位置轉換成RGB的數字,進而讓我們在物件內移動滑鼠的時候改變顏色 ```javascript= var box = document.getElementById('box'); var output = document.getElementById('output123'); box.addEventListener('mousemove', runEvent); function runEvent(e) { box.style.backgroundColor = "rgb("+e.offsetX+","+e.offsetY+",40)"; //直接操作boxCSS修改其背景色為RGB並使用字串串接的方式改變RGB的顏色 } ``` 結果如下: ![](https://i.imgur.com/wQzj2fS.gif) ### 處理上方的Add items ![](https://i.imgur.com/f34bXa1.png) #### 當輸入文字在input區的時候就會觸發事件 ```javascript= var itemInput = document.querySelector('input[type="text"]'); var form = document.querySelector('form'); itemInput.addEventListener('keydown', runEvent); function runEvent(e) { console.log('Event type:'+e.type); } ``` ![](https://i.imgur.com/S6UME9Q.gif) ### 簡介一些其他Event * keydown 按下鍵盤時觸發 * keyup 離開按紐時觸發 * keypress 按住按紐時觸發 * focus 按在input中的時候觸發 * blur 離開focus時觸發 * cut 剪下內容時觸發 * paste 貼上內容時觸發 * input 在input內部做的任何事情跟內文有關係的打字剪下貼上等等都會觸發 * change 當抓取物件發生改變的時候觸發 * submit 當按下submit按鍵後觸發 ```javascript= itemInput.addEventListener('keydown', runEvent); itemInput.addEventListener('keyup', runEvent); itemInput.addEventListener('keypress', runEvent); itemInput.addEventListener('focus', runEvent); itemInput.addEventListener('blur', runEvent); itemInput.addEventListener('cut', runEvent); itemInput.addEventListener('paste', runEvent); itemInput.addEventListener('input', runEvent); itemInput.addEventListener('change', runEvent); itemInput.addEventListener('submit', runEvent); ``` #### 讓輸入的文字內容完整地呈現在瀏覽器上 ```javascript= var itemInput = document.querySelector('input[type="text"]'); var form = document.querySelector('form'); itemInput.addEventListener('keydown', runEvent); function runEvent(e) { console.log('Event type:'+e.type); console.log(e.target.value); //這邊抓取要呈現的地方也就是output123,並使用innerHTML修改內部內容使用文字串接e.target.value的方式呈現 document.getElementById('output123').innerHTML = '<h3>'+e.target.value+'</h3>'; } ``` 結果 ![](https://i.imgur.com/atvgRy2.png) #### 當選取下拉式選單的時候觸發事件使用"change"事件 一點選下拉選單就會觸發事件並印出事件類型 ```javascript= var select = document.querySelector('select'); select.addEventListener('change', runEvent); // select.addEventListener('input', runEvent); 使用input也行得通會產生一樣的結果 function runEvent(e) { console.log('Event type:'+e.type); } ``` ![](https://i.imgur.com/vqeog9W.png) #### 印出選取的下拉式選單的值 使用`console.log(e.target.value);` ```javascript= var select = document.querySelector('select'); select.addEventListener('change', runEvent); // select.addEventListener('input', runEvent); 使用input也行得通會產生一樣的結果 function runEvent(e) { console.log('Event type:'+e.type); console.log(e.target.value); } ``` ![](https://i.imgur.com/kVxXxvy.png) #### 按下submit按鍵後印出type ```javascript= var form = document.querySelector('form'); form.addEventListener('submit', runEvent); function runEvent(e) { e.preventDefault(); console.log('Event type:'+e.type); } ``` ![](https://i.imgur.com/7oZqkGu.png) # JavaScript DOM Crash Course Part - 4 使用上面三個part做出一個真正的小作品來呈現 [作品程式碼](https://codepen.io/bradtraversy/pen/Bwapow) 作品Item Lister ![](https://i.imgur.com/cwzFqpF.png) ## 功能: * 可以在Add items品項並且在submit後加入下方的items * 點X有刪除功能 * 右上角可以搜尋已加入的items(filter) ## HTML: ```htmlembedded= <body> <header id="main-header" class="bg-success text-white p-4 mb-3"> <div class="container"> <div class="row"> <div class="col-md-6"> <h1 id="header-title">Item Lister</h1> </div> <div class="col-md-6 align-self-center"> <input type="text" class="form-control" id="filter" placeholder="Search Items..."> </div> </div> </div> </header> <div class="container"> <div id="main" class="card card-body"> <h2 class="title">Add Items</h2> <form id="addForm" class="form-inline mb-3"> <input type="text" class="form-control mr-2" id="item"> <input type="submit" class="btn btn-dark" value="Submit"> </form> <h2 class="title">Items</h2> <ul id="items" class="list-group"> <li class="list-group-item">Item 1 <button class="btn btn-danger btn-sm float-right delete">X</button></li> <li class="list-group-item">Item 2 <button class="btn btn-danger btn-sm float-right delete">X</button></li> <li class="list-group-item">Item 3 <button class="btn btn-danger btn-sm float-right delete">X</button></li> <li class="list-group-item">Item 4 <button class="btn btn-danger btn-sm float-right delete">X</button></li> </ul> </div> </div> </div> </div> <script src="dom.js"></script> </body> ``` ## JS: ### 取得submit的值並且加入Items最底層 輸入123最底部加入123 ![](https://i.imgur.com/jXzzTOJ.png) ```javascript= //設置兩個變數並且指派抓取好的 form,item 區域 var form = document.getElementById("addForm"); var itemList = document.getElementById("items"); //form submit event 設置form區域submit事件並且設置新的funciton addItem來加入新的items form.addEventListener("submit", addItem); //add item 處理addItem內函式功能的身體 function addItem(e) { e.preventDefault(); // get input value 用抓取到的變數加上(.value)來抓輸入的值 var newItem = document.getElementById("item").value; //create new li element 要增加新欄位到Items下面所以創造一個"li" var li = document.createElement("li"); //add class 其他li有的class他也得加上去 li.className = "list-group-item"; //add text node with input value這邊因為createTextNode是document的方法所以得這樣使用 li.appendChild(document.createTextNode(newItem)); // add del button element 抓取button var deleteBtn = document.createElement("button"); // add classes to delete button 創造className deleteBtn.className = 'btn btn-danger btn-sm float-right delete'; //append text node 把"X"加給delete btn deleteBtn.appendChild(document.createTextNode('X')); //append button to li 把delete btn 加到li li.appendChild(deleteBtn); // append li to list 把il加到list itemList.appendChild(li); } ``` ### 刪除加入的items `confirm()` 用來跳出需要使用者確認的對話視窗,對話視窗中會有確定及取消兩個按鈕。 ```javascript= //delete event 做點擊事件 itemList.addEventListener('click', deleteItem); //remove item function deleteItem(e) { //這邊再判斷是否點擊的元素有包含delete這個class不然點整條form都會delete掉 if (e.target.classList.contains('delete')) { //這邊在使用confirm這個跳出視窗做判斷點擊是的話則執行 if (confirm("Are you sure you want to delete?")) { //這邊把的e參數因為上面的判斷所以已經侷限在delete btn裡面了所以她的parentElement就是li也就是我們要刪除的對象 var li = e.target.parentElement; //使用刪除removeChild元素li itemList.removeChild(li); } } } ``` ### filter篩選內容 `indexOf() ` 方法返回啟動它的對像String中第一次出現的指定值的索引,從fromIndex處進行搜索。**如果未找到該值,則返回-1。** ```javascript= //抓到filter這個id var filter = document.getElementById("filter"); //filter event 創造事件keyup打字觸發事件發動filterItems filter.addEventListener("keyup", filterItems); // filterItems function filterItems(e) { // convert text to lowercase var text = e.target.value.toLowerCase(); //get lis // var items = itemList.getElementsByTagName('li'); var items = document.querySelectorAll('li'); //convert to an array //這邊因為想要使用forEach這個array方法所以直接把items轉換成array Array.from(items).forEach(function (item) { //這邊要使用firstChild來抓取item前面的名字不然就會連後面的"X"一起抓進來 var itemName = item.firstChild.textContent; //抓進來的itemName一樣轉小寫,並使用indexOf判斷text是否不是-1(-1代表沒找到一樣的字串) //不是-1則執行下方的display 顯示出來 //是-1則執行displaynone因為不一樣 if (itemName.toLowerCase().indexOf(text) != -1) { item.style.display = 'block'; } else { item.style.display = 'none'; } }); } ```