1. 程式人生 > >深入分析Javascript事件代理

深入分析Javascript事件代理

很久很久以來,總感覺事件發生與事件代理到之間沒什麼鳥區別。

最近,又看了一下,感覺區別其實真不大!看怎麼理解吧。

要搞清楚什麼是事件代理,就需要先搞清楚什麼是代理。

從商業角度來講,代理就是:我有貨,你沒貨,但丫我沒時間、沒精力全部賣掉,而你一天閒的蛋疼,只剩下時間了。於是,我委託你幫我買,然後哥給你提成。這個過程中,你實際上相當於也有了貨。

OK,怎麼從字面來理解事件代理一詞的含義?後文有講。

一 先看一個真實的,新手繫結onclik事件的例子

如果按照之前的我,我會怎麼給每一個li標籤,新增onlick呢?廢話,要是我,肯定簡單粗暴。
迴圈每一個li,然後全部繫結onlick。

於是我的程式碼應該是這樣子:

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <ul id="thl"> <li>001</li> <li>002</li> <li>003</li> </ul> <script> var thl= document.getElementById('thl'); var aLi = thl.getElementsByTagName('li'); for (var i = 0; i < aLi.length; i++) {   aLi[i].onclick = fn;
} function fn (){ console.log("maomaoliang"); } </script>

好像看起來沒問題了。雖然,有些文章說這樣很消耗效能,但是,我丫電腦好,老子管你效能,不能太認真。

二 突然有一天,我發現通過js新增進來的新的li,沒有繫結onlcik

?
1 2 3 4 var node=document.createElement("li"); var textnode=document.createTextNode("maomaoliang"); node.appendChild(textnode); document.getElementById(
"ul1").appendChild(node);

然後,點選maomaoliang,它並沒有繫結我的onlick,這是為什麼?
哦,原來,我原有的li跟我後面生成的li根本不是同時發生的,在建立新的li元素之前,已經給存在的li加事件了。好吧,好煩啊。

三 那怎麼破?

然後,又好(無)奇(奈)的看了一些文章,原來有個叫事件代理的東西可以用。我就試試看吧!於是改寫了部分程式碼,像這樣:

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 var thl= document.getElementById('thl'); thl.onclick = function(ev) { ev = ev || event; //相容處理 var target = ev.target || ev.srcElement; //找到li元素 if (target.nodeName.toLowerCase() == 'li') { fn(); } }; function fn (){ console.log("maomaoliang"); }

結果,點選新的li,居然也觸發了fn函式。好吧,身為一個好奇心驅動的肉身,我怎麼能不求甚解呢?還是要踏實點,搞清楚這其中的奧祕才行。

於是,看了事件代理的資料。

首先,要知道什麼是事件冒泡:當一個元素上的事件被觸發的時候,比如說滑鼠點選了一個按鈕,同樣的事件將會在那個元素的所有祖先元素中被觸發。這一過程被稱為事件冒泡。

然後,再回到之前的問題“怎麼從字面來理解事件代理一詞的含義”,誰代理了事件?或者事件代理了誰?
以本文的例子來講,看看改動後的程式碼,我把onlick事件繫結到了ul標籤上面,而不是li標籤。於是,當我點選任何一個li標籤(不管是動態生成的還是之前就有的)是,這個事件就像泡泡一樣,冒啊冒。正常的情況下,ul也會繫結onclick,body也會繫結到onclick,也就說它會冒泡到最根層的元素。但我這裡給ul綁定了onlick,那麼這時,ul會把泡泡截住,事件也就停止上升,無法抵達body標籤。

接著, var target = ev.target || ev.srcElement;這一句話,相當於告訴了我,我究竟點的是誰,誰才是target。如果,這個target剛剛好就是li標籤if (target.nodeName.toLowerCase() == 'li'),那麼執行fn函式。

最後,我驕傲的回答了那個問題:table代理了onlick事件!

四 回憶一下事件代理的步驟

父元素繫結事件
父元素知道事件的實際發生目標是誰
我們要對目標進行判斷,如果是我們需要的元素,則發生回撥函式(所以要學好選擇器的使用)

五 最後總結,事件代理兩大好處

效能不小心得到了優化
動態新增的元素也能繫結事件了

六 需要注意的一點是

上述針對的是原生js事件繫結來講的,如果你用到了jquery。並把程式碼改成了如下的樣子:

?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 /*var thl= document.getElementById('ul1'); thl.onclick = function(ev) { ev = ev || event; //相容處理 var target = ev.target || ev.srcElement;   //找到li元素 if (target.nodeName.toLowerCase() == 'li') { //li新增的事件 fn(); } };*/ var node=document.createElement("li"); var textnode=document.createTextNode("maomaoliang"); node.appendChild(textnode); document.getElementById("ul1").appendChild(node); function fn (){ console.log("maomaoliang"); } $("#ul1").click(function(){ fn(); });

這樣一來,新新增的li標籤,也能綁click,是不是很方便、很簡單,是不是感覺學js沒什麼卵用。

哈哈,這樣想很正常,我以前也這麼想,但是,做了一些東西之後,發現jquery還真的不夠用了!但是基本夠用!

雖然,大神們都說要學js,但我還是覺得可以先學jquery,之後再學js,效果也可以的。

相關推薦

深入分析Javascript事件代理

很久很久以來,總感覺事件發生與事件代理到之間沒什麼鳥區別。 最近,又看了一下,感覺區別其實真不大!看怎麼理解吧。 要搞清楚什麼是事件代理,就需要先搞清楚什麼是代理。 從商業角度來講,代理就是:我有貨,你沒貨,但丫我沒時間、沒精力全部賣掉,而你一天閒的蛋疼,只剩下時間了。於是,我委託你幫我買,然後哥給你提成。

JavaScript事件代理事件委托

遍歷 我們 重繪 down 核心 on() his 事件代理 lur 一、概述:   那什麽叫事件委托呢?它還有一個名字叫事件代理,JavaScript高級程序設計上講:事件委托就是利用事件冒泡,只指定一個事件處理程序,就可以管理某一類型的所有事件。那這是什麽意思呢?網上

深入理解JavaScript事件冒泡

一、什麼是事件冒泡 在一個物件上觸發某類事件(比如單擊onclick事件),如果此物件定義了此事件的處理程式,那麼此事件就會呼叫這個處理程式,如果沒有定義此事件處理程式或者事件返回true,那麼這個事件會向這個物件的父級物件傳播,從裡到外,直至它被處理(父級物件所有同類

JavaScript事件代理和委託

<ul id="parent-list"> <li id="post-1">Item 1</li> <li id="post-2">Item 2</li> <li id="post-3">Item 3</li>

javascript事件代理

在程式設計中,如果我們不想或不能夠直接操縱目標物件,我們可以利用delegate建立一個代理物件來呼叫目標物件的方法,從而達到操縱目標物件的目的。毋庸置疑,代理物件要擁有目標物件的引用。我們來看一下javascript的一個最簡單實現: vardelegate =function(client,cli

JavaScript事件代理事件委託)

基本概念 事件代理(Event Delegation),又稱之為事件委託。是JavaScript中常用繫結事件的常用技巧。顧名思義,“事件代理”即是把原本需要繫結在子元素的響應事件(click、keydown......)委託給父元素,讓父元素擔當事件監聽的職務。事件代理的原理是DOM元素的事件

JavaScript事件代理:尋找target目標元素、求結點深度

基礎知識儲備 本文的出彩之處在最後兩部分,前面只是基礎介紹。 JS中的事件代理,網上有很多大神已經介紹的非常完美了,這裡無需我的贅述。在學習事件代理之前,最好把事件模型學習了,就是捕獲階段、目標階段、冒泡階段 那些事情。這裡,我推薦兩篇別人的文章:

JavaScript事件代理和委託(Delegation)

<ul id="parent-list"> <li id="post-1">Item 1</li> <li id="post-2">Item 2</li> <li id="post-3">Item 3</li>

javascript中的事件委托或是事件代理詳解

開始 reat 事件 網上 html 比較 移動 由於 move 概述: 那什麽叫事件委托呢?它還有一個名字叫事件代理,JavaScript高級程序設計上講:事件委托就是利用事件冒泡,只指定一個事件處理程序,就可以管理某一類型的所有事件。那這是什麽意思呢?網上的各位大牛們講

深入理解JavaScript的閉包特性如何給循環中的對象添加事件

彈出 所有 了解 ext catch 形參 efi 運行期 -- 初學者經常碰到的,即獲取HTML元素集合,循環給元素添加事件。在事件響應函數中(event handler)獲取對應的索引。但每次獲取的都是最後一次循環的索引。原因是初學者並未理解JavaScri

JavaScript事件模型及事件代理

監聽器 abort rop char 方便 listener 新版 media 事件處理 事件模型  JavaScript事件使得網頁具備互動和交互性,我們應該對其深入了解以便開發工作,在各式各樣的瀏覽器中,JavaScript事件模型主要分為3種:原始事件模型、DOM2事

深入理解JavaScript事件循環(Event Loop)

out star event ron 來看 runt 針對 我們 == 一、什麽是事件循環 JS的代碼執行是基於一種事件循環的機制,之所以稱作事件循環,MDN給出的解釋為 因為它經常被用於類似如下的方式來實現 while (queue.waitForMe

Javascript是單執行緒的深入分析

面試的時候發現99%的童鞋不理解為什麼JavaScript是單執行緒的卻能讓AJAX非同步傳送和回撥請求,還有setTimeout也看起來像是多執行緒的?還有non-blocking IO, event loop等概念很不清楚。來深入分析一下: 首先看下面的程式碼: function foo() {

JavaScript中的事件代理

首先,事件有三個階段:捕獲、目標、冒泡(不瞭解的自行搜尋)。 那麼,當我需要給ul下1000個li都要繫結點選事件,應該用for迴圈遍歷?答案當然no。就算可以,但是你要明白,這麼做是要承擔足夠大的效能風險,因為首先你得用getElementByTagName("li")

JavaScript事件物件深入詳解

本文例項講述了JavaScript事件物件。分享給大家供大家參考,具體如下: 觸發 DOM 上的事件時,會生成一個事件物件 event,它包含著所有與事件有關的資訊,諸如導致事件的元素、事件的型別以及其他與特定事件相關的資訊。所有的瀏覽器都支援 event 物件,但支援的方式不同。

javascript事件代理

如果你想給網頁新增點JavaScript的互動性,也許你已經聽過JavaScript的事件代理(event delegation),並且覺得這是那些發燒友級別的JavaScript程式設計師才會關心的什麼費解的設計模式之一。事實上,如果你已經知道怎麼新增JavaScript

javascript-委託事件(事件代理)

1.什麼是委託事件? 委託事件也叫做事件代理意思是一樣的,就好像精靈圖也叫 雪碧圖!!!只是不同叫法. 試想一下:假設公司裡每次收快遞的時候員工都跑到公司門口去收自己的快遞,如果同時多個人也同樣去收自己快遞這樣公司就秩序混輪了!如果委託給前臺妹子去收快遞然後

JavaScript: 最簡單的事件代理(JS Event Proxy)原理程式碼

假設有HTML <ul id="parent-list"> <li id="post-1">Item 1</li> <li id="p

關於JavaScript中的事件代理

今天面試某家公司Web前端開發崗位,前面的問題回答的都還算湊活,並且又問了一下昨天面試時做的一道陣列去重問題的解題思路(關於陣列去重問題,可以觀賞我前幾天寫的:http://www.cnblogs.com/craftsman-gao/p/4766223.html。幸好前幾

javascript開發:ES5與ES6的“this”深入分析

ES6中新增了箭頭函式這種語法,箭頭函式以其簡潔性和方便獲取this的特性,俘獲了大批粉絲兒 它也可能是面試中的寵兒, 我們關鍵要搞清楚 箭頭函式和普通函式中的this 一針見血式總結: 普通函式中的this: 1. this總是代表它的直接呼叫者, 例如 obj