節點node的刪除方法:node.removeChild(nodes),
回顧一下節點的添加方法:node.appendChild(nodes),html
節點的賦值方法:node.cloneNode();
須要注意的地方:node
注意:他們之間是有區別的編程
有沒有一種方式是效率比較高的?有!,使用數組加innerHTMLwindows
function fn() { var d1 = +new Date(); var array = []; for (var i = 0; i < 1000; i++) { array.push('<div style="width:100px; height:2px; border:1px solid blue;"></div>'); } document.body.innerHTML = array.join(''); var d2 = +new Date(); console.log(d2 - d1); } fn();
核心知識點。就是一系列的標準編程接口數組
DOM樹,是比價核心的,經過DOM獲取到的是一個對象,有它的屬性,有它的方法瀏覽器
主要是前面說的三種write,innerHTML,createElementapp
如下是具體相關操做!
dom
- 使用on開頭的時間 - 而後給一個函數btn.onclick = function(){} - 這種方式註冊事件是惟一的,若是後面還有,會發生覆蓋
這就是比較高端的方式了。addEvenListener(),若是是ie9以前,使用attachEvent, 同一個元素能夠有多個監聽器,按註冊的順序執行
//公式 把監聽器放在eventTarget上面 eventTarget.addEventListener(Type,Listener[,userCapture]) //參數說明》 type:事件類型的字符串,好比click ,這裏不須要帶有on listener:事件的處理函數,事件發生的時候會調用 userCapture:是一個布爾值,可選參數,默認是false與事件流有關 eventTarget.attachEvent(eventNameWithON,callback)方法將指定的監聽器註冊到 eventTarget(目標對象) 上,當該對象觸發指定的事件時,指定的回調函數就會被執行。 這裏的時間須要指定on ,
對於事件的兼容性,咱們能夠直接封裝一個函數去處理函數
evemtTarget.onclick = null; eventTarget.removeEventListener(Type,Listener[,userCapture]) eventTarget.detachEvent(eventNameWithON,callback)
<div>1</div> <div>2</div> <div>3</div> <script> var divs = document.querySelectorAll('div'); divs[0].onclick = function() { alert(11); // 1. 傳統方式刪除事件 divs[0].onclick = null; } // 2. removeEventListener 刪除事件 divs[1].addEventListener('click', fn) // 裏面的fn 不須要調用加小括號 function fn() { alert(22); divs[1].removeEventListener('click', fn); } // 3. detachEvent divs[2].attachEvent('onclick', fn1); function fn1() { alert(33); divs[2].detachEvent('onclick', fn1); } </script>
一樣的對於兼容性的處理,咱們也可使用兼容性的封裝函數
性能
所謂的事件流指的是從頁面中接受到事件的順序。
咱們的事件狀態一共與三種 捕獲狀態——>當前目標階段——>冒泡階段
js在執行代碼的時候,只能執行其中的捕獲或者冒泡階段,
onclick還有attachEvent只能獲得冒泡,
對於另外的一個綁定事件的函數,第三個值userCapture前面的值,默認是false表示是在冒泡階段調用處理程序,若是是true就是在捕獲的時候執行。
如下的時間是沒有冒泡的,onblur,onfocus,onmouseenter,onmouseleave
事件冒泡
<div class="father"> <div class="son">son盒子</div> </div> <script> // onclick 和 attachEvent(ie) 在冒泡階段觸發 // 冒泡階段 若是addEventListener 第三個參數是 false 或者 省略 // son -> father ->body -> html -> document var son = document.querySelector('.son'); // 給son註冊單擊事件 son.addEventListener('click', function() { alert('son'); }, false); // 給father註冊單擊事件 var father = document.querySelector('.father'); father.addEventListener('click', function() { alert('father'); }, false); // 給document註冊單擊事件,省略第3個參數 document.addEventListener('click', function() { alert('document'); }) </script>
事件捕獲
<div class="father"> <div class="son">son盒子</div> </div> <script> // 若是addEventListener() 第三個參數是 true 那麼在捕獲階段觸發 // document -> html -> body -> father -> son var son = document.querySelector('.son'); // 給son註冊單擊事件,第3個參數爲true son.addEventListener('click', function() { alert('son'); }, true); var father = document.querySelector('.father'); // 給father註冊單擊事件,第3個參數爲true father.addEventListener('click', function() { alert('father'); }, true); // 給document註冊單擊事件,第3個參數爲true document.addEventListener('click', function() { alert('document'); }, true) </script>
事件發生後,跟事件相關的一系列信息數據的集合都放到這個對象裏面,這個對象就是事件對象。
只要「||」前面爲false, 無論「||」後面是true 仍是 false,都返回 「||」 後面的值。 只要「||」前面爲true, 無論「||」後面是true 仍是 false,都返回 「||」 前面的值。
<div>123</div> <script> var div = document.querySelector('div'); div.onclick = function(e) { // 事件對象 e = e || window.event; console.log(e); } </script>
this 是事件綁定的元素(綁定這個事件處理函數的元素) 。
e.target 是事件觸發的元素。
常狀況下terget 和 this是一致的, 但有一種狀況不一樣,那就是在事件冒泡時(父子元素有相同事件,單擊子元素,父元素的事件處理函數也會被觸發執行), 這時候this指向的是父元素,由於它是綁定事件的元素對象, 而target指向的是子元素,由於他是觸發事件的那個具體元素對象。
<div>123</div> <script> var div = document.querySelector('div'); div.addEventListener('click', function(e) { // e.target 和 this指向的都是div console.log(e.target); console.log(this); }); </script>
事件冒泡下的e.target和this
<ul> <li>abc</li> <li>abc</li> <li>abc</li> </ul> <script> var ul = document.querySelector('ul'); ul.addEventListener('click', function(e) { // 咱們給ul 綁定了事件 那麼this 就指向ul console.log(this); // ul // e.target 觸發了事件的對象 咱們點擊的是li e.target 指向的就是li console.log(e.target); // li }); </script>
html中一些標籤有默認行爲,例如a標籤被單擊後,默認會進行頁面跳轉。
<a href="http://www.baidu.com">百度</a> <script> // 2. 阻止默認行爲 讓連接不跳轉 var a = document.querySelector('a'); a.addEventListener('click', function(e) { e.preventDefault(); // dom 標準寫法 }); // 3. 傳統的註冊方式 a.onclick = function(e) { // 普通瀏覽器 e.preventDefault(); 方法 e.preventDefault(); // 低版本瀏覽器 ie678 returnValue 屬性 e.returnValue = false; // 咱們能夠利用return false 也能阻止默認行爲 沒有兼容性問題 return false; } </script>
e.stopPropagation()
e.canceBubble = true;
<div class="father"> <div class="son">son兒子</div> </div> <script> var son = document.querySelector('.son'); // 給son註冊單擊事件 son.addEventListener('click', function(e) { alert('son'); e.stopPropagation(); // stop 中止 Propagation 傳播 window.event.cancelBubble = true; // 非標準 cancel 取消 bubble 泡泡 }, false); var father = document.querySelector('.father'); // 給father註冊單擊事件 father.addEventListener('click', function() { alert('father'); }, false); // 給document註冊單擊事件 document.addEventListener('click', function() { alert('document'); }) </script>
一樣的這裏也有兼容性的處理方法
if(e && e.stopPropagation{ e.stopPropagation() }else{ windows.evet.canceBubble = true; }
說白了就是,不給子元素註冊事件,給父元素註冊事件,把處理代碼在父元素的事件中執行。
委託的原理:利用了冒泡
:給父元素註冊事件,利用事件冒泡,當子元素的事件觸發,會冒泡到父元素,而後去控制相應的子元素。這麼作,能夠提升一些性能
咱們只操做了一次 DOM ,提升了程序的性能。
動態新建立的子元素,也擁有事件。
<ul> <li>知否知否,點我應有彈框在手!</li> <li>知否知否,點我應有彈框在手!</li> <li>知否知否,點我應有彈框在手!</li> <li>知否知否,點我應有彈框在手!</li> <li>知否知否,點我應有彈框在手!</li> </ul> <script> // 事件委託的核心原理:給父節點添加偵聽器, 利用事件冒泡影響每個子節點 var ul = document.querySelector('ul'); ul.addEventListener('click', function(e) { // e.target 這個能夠獲得咱們點擊的對象 e.target.style.backgroundColor = 'pink'; }) </script>