這兩天更進一步的了解了JS,老師讓我們用原生的js編寫圖片切換和改變點擊按鈕樣式,就是讓我們學會怎么去把一個問題拆分,怎么將一個大問題拆分成許多的小問題,再用函數封裝起來。比如一個點擊按鈕,讓其點擊時背景色發生改變,點擊另一個時,上一個按鈕要變回原來本有的顏色:這個問題用jquery,一行代碼就搞定,但是用原生js就得分三個部分來考慮:
1.添加改變背景的樣式。
2.怎么獲取到除了當前點擊的按鈕以外其他的兄弟節點。
3.怎么去除按鈕的樣式屬性。
也講了事件委托,實現了可以刪除新添加的元素的功能。后面我會把代碼貼出來。
這兩天上課講得一些筆記:
1.需要注意的兩個細節:(1)、不要隨意修改別的對象的屬性值,比如圖片切換這個例子,要獲取li的索引時,不能改變節點的index屬性。
(2)、實現某個功能時,要封裝好業務邏輯,做到改變dom節點時,不用改變業務邏輯。
2.屬性:(1)、dom.parentNode :dom節點的父元素。
(2)、dom.children : Element的屬性,代表元素節點的所有子元素,Element是Node的擴展,也是他多種類型中的一種。
(3)、dom.childNode: Node中的屬性,代表節點的所有子元素,而節點又分為元素節點、文本節點、屬性節點、注釋節點、文檔節點等。
e.g:
Node的children屬性為undefined.因為Node代表DOM中的節點,而上面也提到了children只是元素節點的屬性。
(4)、dom.className : 為節點添加class名。
3.方法 : (1)、dom.appendChild :appendChild() 方法向節點添加最后一個子節點。
(2)、dom.removeChild: removeChild() 方法指定元素的某個指定的子節點,以 Node 對象返回被刪除的節點,如果節點不存在則返回 null。
4. push()方法 : 用法: arr.push(Arr[i]) ,將Arr的第i個元素插入到arr數組中。
5. "==" 和"==="的區別: "=="只會比較值是否相等,比如 1 == "1" 是對的,但會true,而"==="是值和數據類型都會比較,完全相等才返回true,所以1 === "1" 返回false。
6. 關於函數講了兩個重要的點:(1)、函數可以被調用很多次,調用執行后,函數就會被銷毀,這是函數的機制。
(2)、閉包是里面的函數若沒有調用執行,那么外部的函數不會被銷毀。
7. 原生js創建文本節點、元素節點,刪除節點,添加文本節點到元素節點:
(1)、var txt = document.createTextNode("text"); //創建文本節點的方法。
(2)、var elem = document.createElement("li"); //創建元素節點 "li"。
(3)、elem.appendChild(txt); //添加文本節點到元素節點的最后子節點上。
(4)、ul.appendChild(elem) ; //在ul里添加li元素節點。
(5)、ul.removeChild(elem); //刪除ul中的elem元素節點。
下面是用這些方法實現的添加水果和刪除水果的功能的代碼:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>dom節點添加刪除</title> 6 <style> 7 span{ 8 cursor: pointer; 9 } 10 </style> 11 </head> 12 <body> 13 <input type="text" id="foods"> 14 <input type="button" id="add" value="添加"> 15 <ul id="ul"> 16 <li>蘋果 <span class="del">刪除</span> </li> 17 <li>香蕉 <span class="del">刪除</span> </li> 18 <li>橙子 <span class="del">刪除</span> </li> 19 <li>桑葚 <span class="del">刪除</span> </li> 20 </ul> 21 <script> 22 var foods = document.getElementById("foods"); 23 var add = document.getElementById("add"); 24 var ul = document.getElementById("ul"); 25 var li = ul.getElementsByTagName("li") 26 add.onclick = function(){ 27 var elemLi = document.createElement("li"); 28 var foodsVal = foods.value; 29 var txt = document.createTextNode(foodsVal); 30 elemLi.appendChild(txt); 31 ul.appendChild(elemLi); 32 var elemSpan = document.createElement("span"); 33 elemSpan.className = "del"; 34 var txtDelete = document.createTextNode(" 刪除"); 35 elemSpan.appendChild(txtDelete); 36 elemLi.appendChild(elemSpan); 37 } 38 //下面的刪除節點用的是事件委托,可以刪除新添加上li。 39 ul.onclick = function(event){ 40 if(event.target.className == "del"){ //event.target就代表在ul的所有子元素下當前點擊的元素。 41 ul.removeChild(event.target.parentNode); 42 } 43 }
8. 事件冒泡和時間捕獲的問題:
這里就要提到addEventListener()方法,addEventListener()與removeEventListener()用於處理指定和刪除事件處理程序操作。所有的DOM節點中都包 含這兩種方 法,並且它們都接受3個參數:要處理的時間名、作為事件處理程序的函數和一個布爾值。最后這個布爾值參數是true,表示在捕獲階段調用事件處 理程序;如果是false, 表示在冒泡階段調用事件處理程序。
addEventListener的參數一共有三個,語法為:
element.addEventListener(type,listener,useCapture)
下面是需要注意的事項:
(1)其中element是要綁定函數的對象。
(2)type是事件名稱,要注意的是"onclick"要改為"click","onblur"要改為"blur",也就是說事件名不要帶"on"。
(3)listener當然就是綁定的函數了,記住不要跟括號。
(4)最后一個參數是個布爾值,表示該事件的響應順序。
下面是關於addEventListener的一個小例子:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>事件冒泡</title> 6 <style> 7 #outer,#inner,#con{ 8 margin: 0 auto; 9 padding: 50px 0; 10 } 11 #outer{ 12 height: 250px; 13 width: 300px; 14 background-color: #999; 15 } 16 #con{ 17 height: 150px; 18 width: 200px; 19 background-color: #ccc; 20 } 21 #inner{ 22 height: 50px; 23 width: 100px; 24 background-color: #eee; 25 } 26 </style> 27 </head> 28 <body> 29 <div id="outer"> 30 <div id="con"> 31 <div id="inner"></div> 32 </div> 33 </div> 34 <script> 35 var outer = document.getElementById("outer"); 36 var inner = document.getElementById("inner"); 37 var con = document.getElementById("con"); 38 inner.addEventListener("click",function(){ 39 console.log("inner"); 40 },true) 41 42 outer.addEventListener("click",function(){ 43 console.log("outer"); 44 },true) 45 con.addEventListener("click",function(){ 46 console.log("con"); 47 },true) 48 49
上面這個例子中,如果你點擊id為inner的盒子,控制台會輸出 outer con inner 以事件捕獲的順序調用程序。如果不用這個方法,只用單純的點擊事件,那么他會按冒泡 順序調用執行程序。
9.回調函數
定義:將一個函數作為參數傳給另一個函數或者方法,常見的setInterval(function(),1000) 就是將function函數傳到了setInterval方法中。上面的 addEventListener方法也是回調函數。
下面有個例子
1 function fun(Fun){ //函數名fun 形參是Fun 2 Fun(); //這里調用名為Fun的函數,因為程序走到這里並沒有執行,因為在后面調用是才執行。 3 console.log("xixi~"); 4 } 5 fun(function(){ //調用函數fun ,實參為一個函數,這里這個函數就是作為參數傳給了fun函數,這時候fun函數執行,Fun()調用函數就可以執行被當作參數的函數了,即控制台會輸出haha~。 6 console.log("haha~"); 7 })
下面是用原生JS編寫的圖片切換按鈕背景顏色改變的例子:
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>banner_roll_change</title> 6 <style> 7 *{ 8 margin: 0; 9 padding: 0; 10 list-style: none; 11 } 12 div{ 13 margin: 0 auto; 14 width: 30%; 15 height: 300px; 16 position: relative; 17 } 18 div img{ 19 width: 100%; 20 } 21 ul{ 22 position: absolute; 23 left: 50%; 24 margin-left: -60px; 25 } 26 ul li{ 27 float: left; 28 width: 10px; 29 height: 10px; 30 background-color: #999; 31 border-radius: 50%; 32 margin-right: 20px; 33 } 34 /* ul li a{ 35 display: block; 36 }*/ 37 .active{ 38 background-color: red; 39 } 40 </style> 41 </head> 42 <body> 43 <div> 44 <img src="images/5.jpg" alt="" id="pic"> 45 </div> 46 <ul> 47 <li class="list"><a href="#"></a></li> 48 <li class="list"><a href="#"></a></li> 49 <li class="list"><a href="#"></a></li> 50 <li class="list"><a href="#"></a></li> 51 </ul> 52 // <script src="jquery-1.11.1.js"></script> 53 <script> 54 55 //用jquery編寫點擊背景色改變 56 // $("a").click(function(){ 57 // $(this).addClass("active").parent().siblings().find("a").removeClass("active"); 58 // }) 59 60 61 //用原聲js 62 63 var lis = document.getElementsByClassName("list"); 64 var pic = document.getElementById("pic"); 65 var picArr = ["images/5.jpg","images/6.jpg","images/7.jpg","images/8.jpg"]; 66 for(var i = 0;i<lis.length;i++){ 67 lis[i].onclick = function(ind){ 68 return function(){ 69 pic.src = picArr[ind]; 70 addClass(this,"active"); 71 var sib = siblings(this); 72 for(var j = 0;j<sib.length;j++){ 73 removeClass(sib[j],"active"); 74 } 75 } 76 }(i) 77 } 78 function addClass(obj,name){ //添加樣式函數 79 obj.className = obj.className + " " + name; 80 } 81 function siblings(obj){ //獲取到除當前按鈕以外其他按鈕 82 var sibArr = obj.parentNode.children; 83 var sibNewArr = []; 84 for(var i = 0;i<sibArr.length;i++){ 85 if(sibArr[i] != obj){ 86 sibNewArr.push(sibArr[i]); 87 } 88 } 89 return sibNewArr; 90 } 91 function removeClass(obj,name){ //刪除樣式函數 92 var classStr = obj.className; 93 var classArr = classStr.split(" "); 94 var classNewArr = []; 95 for(var i = 0;i<classArr.length;i++){ 96 if(classArr[i] != name){ 97 classNewArr.push(classArr[i]); 98 } 99 } 100 obj.className = classNewArr.join(" "); 101 } 102 </script> 103 </body> 104 </html>