今天面試某家公司Web前端開發崗位,前面的問題回答的都還算湊活,而且又問了一下昨天面試時作的一道數組去重問題的解題思路(關於數組去重問題,能夠觀賞我前幾天寫的:http://www.cnblogs.com/craftsman-gao/p/4766223.html。幸虧前幾天專門看過這個問題,答題時才能輕鬆應對啊),由於這些之前都有過研究,因此回答起來並無太大困難。然而,最後面試官又出了一道代碼題讓我漲姿式了。題目自己很簡單:一個ul中有一千個li,如何給這一千個li綁定一個鼠標點擊事件,當鼠標點擊時alert出這個li的內容和li的位置座標xy,javascript
<ul id="ulItem"> <li id="li1">1</li> <li id="li2">2</li> <li id="li3">3</li> ... <li id="li1000">1000</li> </ul>
須要考慮到瀏覽器兼容性、事件冒泡、效率等問題。看到問題後我就直接在紙上寫下了以下答案:html
var ulItem = document.getElementById("ulItem"); var lis = document.getElementsByTagName("li"); for(var i=0; i<lis.length; i++){ lis[i].onclick = function(){ alert("內容:"+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; }
return {x:x, y:y}; }
寫完了又看了一遍感受不必考慮兼容性、事件冒泡啊。效率的話,想了想,也想不出怎麼提高了,就這樣給面試官看了。面試官人也挺好的,他看了以後說:你並無考慮到我說的重點啊,你這樣1000次循環添加點擊事件效率是很低的。而後就跟我講了利用事件冒泡的特性,來提升效率,即事件代理(ps:之前作項目有遇到過要阻止事件冒泡的時候,但利用事件冒泡特性提升效率卻還徹底不知道)。聽了面試官講的漲了姿式,回來後本身也上網查了一下,如今本身再總結下當作記錄本身學習的過程吧:前端
事件代理(Event Delegation),又稱之爲事件委託。是 JavaScript 中經常使用綁定事件的經常使用技巧。顧名思義,「事件代理」便是把本來須要綁定的事件委託給父元素,讓父元素擔當事件監聽的職務。java
爲何要這麼作?衆所周知,DOM操做是十分消耗性能的,因此重複的事件綁定簡直是性能殺手。而事件代理的核心思想,就是經過儘可能少的綁定,去監聽儘可能多的事件。程序猿的事,沒代碼說個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}; }
嗯,如今代碼去掉了for循環,提升了效率,也有了兼容性方面的處理,感受這個答案應該能夠了吧。上面說的也就是爲了一道筆試題,下面就再本着學術研究的思想說說事件代理:數組
在傳統的事件處理中,你按照須要爲每個元素添加或者是刪除事件處理器。然而,事件處理器將有可能致使內存泄露或者是性能降低——你用得越多這種風險就越大。JavaScript事件代理則是一種簡單的技巧,經過它你能夠把事件處理器添加到一個父級元素上,這樣就避免了把事件處理器添加到多個子級元素上。事件代理用到了兩個在JavaSciprt事件中常被忽略的特性:事件冒泡以及目標元素。當一個元素上的事件被觸發的時候,好比說鼠標點擊了一個按鈕,一樣的事件將會在那個元素的全部祖先元素中被觸發。這一過程被稱爲事件冒泡;這個事件從原始元素開始一直冒泡到DOM樹的最上層。任何一個事件的目標元素都是最開始的那個元素,在咱們的這個例子中也就是按鈕,而且它在咱們的事件對象中以屬性的形式出現。使用事件代理,咱們能夠把事件處理器添加到一個元素上,等待一個事件從它的子級元素裏冒泡上來,而且能夠得知這個事件是從哪一個元素開始的。瀏覽器
關於事件代理,今天也是初次接觸,就先寫到這吧。性能