淺析javascript中的事件代理
本文的主要內(nèi)容是根據(jù)前不久面試某家公司W(wǎng)eb前端開發(fā)崗位,面試時(shí)做的一道數(shù)組去重問題的解題思路進(jìn)行整理的,分享給大家。
題目本身很簡(jiǎn)單:一個(gè)ul中有一千個(gè)li,如何給這一千個(gè)li綁定一個(gè)鼠標(biāo)點(diǎn)擊事件,當(dāng)鼠標(biāo)點(diǎn)擊時(shí)alert出這個(gè)li的內(nèi)容和li的位置坐標(biāo)xy,
<ul id="ulItem"> <li id="li1">1</li> <li id="li2">2</li> <li id="li3">3</li> ... <li id="li1000">1000</li> </ul>
需要考慮到瀏覽器兼容性、事件冒泡、效率等問題??吹絾栴}后我就直接在紙上寫下了如下答案:
var ulItem = document.getElementById("ulItem"); var lis = document.getElementsByTagName("li"); for(var i=0; i<lis.length; i++){ lis[i].onclick = function(){ alert("內(nèi)容:"+this.innerHTML); alert("位置:"+getElementPosition(this).x+","+getElementPosition(this).y; } } function getElementPosition(e){ var x=0,y=0; while(e != null){ x += e.offsetLeft; y += e.offsetTop; e = e.offsetParent; }<br> return {x:x, y:y}; }
面試結(jié)果:寫完了又看了一遍感覺沒必要考慮兼容性、事件冒泡啊。效率的話,想了想,也想不出怎么提升了,就這樣給面試官看了。面試官人也挺好的,他看了之后說:你并沒有考慮到我說的重點(diǎn)啊,你這樣1000次循環(huán)添加點(diǎn)擊事件效率是很低的。然后就跟我講了利用事件冒泡的特性,來提高效率,即事件代理(ps:以前做項(xiàng)目有遇到過要阻止事件冒泡的時(shí)候,但利用事件冒泡特性提高效率卻還完全不知道)。聽了面試官講的漲了姿勢(shì),回來后自己也上網(wǎng)查了一下,現(xiàn)在自己再總結(jié)下當(dāng)做記錄自己學(xué)習(xí)的過程吧:
事件代理(Event Delegation),又稱之為事件委托。是 JavaScript 中常用綁定事件的常用技巧。顧名思義,“事件代理”即是把原本需要綁定的事件委托給父元素,讓父元素?fù)?dān)當(dāng)事件監(jiān)聽的職務(wù)。
為什么要這么做?眾所周知,DOM操作是十分消耗性能的,所以重復(fù)的事件綁定簡(jiǎn)直是性能殺手。而事件代理的核心思想,就是通過盡量少的綁定,去監(jiān)聽盡量多的事件。程序猿的事,沒代碼說個(gè)J8,下面貼出代碼:
var ulItem = document.getElementById("ulItem"); ulItem.onclick = function(e){ e = e || window.event;//這一行和下一行是為了兼容IE8以及之前版本 var target = e.target || e.srcElement; if(target.tagName.toLowerCase() === "li"){ alert(target.innerHTML); alert("位置為:"+getElementPosition(target).x+","+getElementPosition(target).y); } } function getElementPosition(e){ var x=0,y=0; while(e != null){ x += e.offsetLeft; y += e.offsetTop; e = e.offsetParent; } return {x:x, y:y}; }
嗯,現(xiàn)在代碼去掉了for循環(huán),提高了效率,也有了兼容性方面的處理,感覺這個(gè)答案應(yīng)該可以了吧。上面說的也就是為了一道筆試題,下面就再本著學(xué)術(shù)研究的思想說說事件代理:
在傳統(tǒng)的事件處理中,你按照需要為每一個(gè)元素添加或者是刪除事件處理器。然而,事件處理器將有可能導(dǎo)致內(nèi)存泄露或者是性能下降——你用得越多這種風(fēng)險(xiǎn)就越大。JavaScript事件代理則是一種簡(jiǎn)單的技巧,通過它你可以把事件處理器添加到一個(gè)父級(jí)元素上,這樣就避免了把事件處理器添加到多個(gè)子級(jí)元素上。事件代理用到了兩個(gè)在JavaSciprt事件中常被忽略的特性:事件冒泡以及目標(biāo)元素。當(dāng)一個(gè)元素上的事件被觸發(fā)的時(shí)候,比如說鼠標(biāo)點(diǎn)擊了一個(gè)按鈕,同樣的事件將會(huì)在那個(gè)元素的所有祖先元素中被觸發(fā)。這一過程被稱為事件冒泡;這個(gè)事件從原始元素開始一直冒泡到DOM樹的最上層。任何一個(gè)事件的目標(biāo)元素都是最開始的那個(gè)元素,在我們的這個(gè)例子中也就是按鈕,并且它在我們的事件對(duì)象中以屬性的形式出現(xiàn)。使用事件代理,我們可以把事件處理器添加到一個(gè)元素上,等待一個(gè)事件從它的子級(jí)元素里冒泡上來,并且可以得知這個(gè)事件是從哪個(gè)元素開始的。
關(guān)于事件代理,今天也是初次接觸,就先寫到這吧,希望對(duì)大家的學(xué)習(xí)有所幫助。
相關(guān)文章
javascript+css實(shí)現(xiàn)進(jìn)度條效果
這篇文章主要為大家詳細(xì)介紹了javascript+css實(shí)現(xiàn)進(jìn)度條效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-03-03純JS實(shí)現(xiàn)的讀取excel文件內(nèi)容功能示例【支持所有瀏覽器】
這篇文章主要介紹了純JS實(shí)現(xiàn)的讀取excel文件內(nèi)容功能,結(jié)合實(shí)例形式分析了基于js相關(guān)插件進(jìn)行Excel文件讀取的相關(guān)操作技巧,需要的朋友可以參考下2018-06-06uniapp實(shí)現(xiàn)左右聯(lián)動(dòng)商品分類頁面
一個(gè)電商的app,商品的展示是必不可少的,聯(lián)動(dòng)分類展示是很常見的,下面這篇文章主要給大家介紹了關(guān)于uniapp實(shí)現(xiàn)左右聯(lián)動(dòng)商品分類頁面的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-06-06精彩的Bootstrap案例分享 重點(diǎn)在注釋!(選項(xiàng)卡、柵格布局)
這篇文章主要為大家分享了一個(gè)精彩的Bootstrap案例,涉及到了選項(xiàng)卡、柵格布局,關(guān)鍵重點(diǎn)在注釋,感興趣的小伙伴們可以參考一下2016-07-07JavaScript中的this指向綁定規(guī)則及常見面試總結(jié)
這篇文章主要為大家介紹了JavaScript中的this指向綁定規(guī)則及箭頭韓碩中的this指向,還b包含了常見面試總結(jié),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12微信小程序跨頁面?zhèn)鬟fdata數(shù)據(jù)方法解析
這篇文章主要介紹了微信小程序跨頁面?zhèn)鬟fdata數(shù)據(jù)方法解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-12-12