web前端开发技术第一版答案 |
web前端开发技术 清华 |
新的前端开发技术 |
在JavaScript中经常会出现delegate这词,我们都知道它的字面意思就是委托/代理,它有什么作用呢?它的原理又是什么呢?
我们先来看一个例子: 假设有一个 ul 的父节点,包含了很多个 li 的子节点,每个li子节点中又包含了button。当某个button被点击时,隐藏其父节点li。
html代码如下:
<html>
<body>
<ul>
<li><button>Button A</button></li>
<li><button>Button B</button></li>
<li><button>Button C</button></li>
</ul>
</body>
</html>[/code]
通常的写法:
[code] <script type=”text/JavaScript”>
window.onload=function(){
var oUl = document.getElementsByTagName('ul')[0];
var aBtn =oUl.getElementsByTagName('button');
for(var i=0;i<aBtn.length;i++)
{
aBtn[i].onclick=function(){
this.parentNode.style.display="none";
}
}
}
</script>[/code]
以上代码,我们创建了太多的处理函数。为每一个匹配的 button添加事件处理函数。
简单的方法是使用事件代理机制:
[code] <script type=”text/JavaScript”>
//事件绑定函数
function myAddEvent (obj,ev,fn){
if(obj.attachEvent)
{
obj.attachEvent("on"+ev,fn); //支持IE
}
else{
obj.addEventListener(ev,fn,false); //非IE
}
}
window.onload=function(){
// 获取父节点,并为它添加一个click事件
var oUl = document.getElementsByTagName('ul')[0];
myAddEvent(oUl,"click",function (ev){
//获取事件对象,IE支持event,非IE支持ev
var oEvent = ev||event;
//获取用户当前点击的事件对象,IE支持srcElement,非IE支持target
var oTarge =oEvent.target||oEvent.srcElement;
//检查事件源oTarge是否为button
if(oTarge && oTarge.nodeName.toLowerCase() == "button")
{
oTarge.parentNode.style.display="none";
}
});
}
</script>[/code]
为父节点绑定了一个click事件,当子节点被点击的时候,click事件会从子节点开始向上冒泡。父节点捕获到事件之后,判断是当前触发事件的对象,即用户真正单击到的对象,并且通过oTarge.nodeName来判断是否为我们需要处理的节点。从而可以获取到相应的信息,并作处理。
我们来总结一下,事件委托/代理有哪些优点
1.需要创建和驻留在内存中的事件处理函数减少了,提高了性能。我们不需要为每个元素都添加监听函数,对于父节点下面类似的子元素,只需通过委托给父节点的监听函数来处理。
2.减少了JavaScript和DOM节点之间的关联,从而降低了因循环引起的内存泄漏概率。
3.方便动态添加和修改元素,不会因为元素变动而修改事件绑定。
相信你是和现在的我一样,已经迫不及待地想知道JavaScript事件委托/代理是什么,以及它的工作机制了
什么是JavaScript事件委托/代理
当我们需要给很多元素添加事件时,我们可以将事件添加到它们的父节点上,从而把事件委托给了父节点来触发处理函数。
JavaScript事件的工作原理
当用户点击一个元素时,一个事件就会被产生去通知用户当前的行为。事件在分发派遣时会有三个阶段:
1.捕获阶段: Capturing
2.目标阶段: Target
3.冒泡阶段: Bubbling
事件捕获:当某个元素被触发某个事件时(如 onclick),顶层对象document就会发出一个事件流,随着DOM树的节点向目标元素流去,直到达到事件真正发生的目标元素。
事件目标:当到达目标元素的时,执行目标元素该绑定事件的相应处理函数。
事件冒泡:从目标元素开始,按原路返回,直到退出整个DOM树。途中如果有节点绑定了相应的事件处理函数,这些函数都会被一次触发。(若想阻止事件冒泡,可以使用e.stopPropagation()(Firefox)或者e.cancelBubble=true(IE)来阻止事件的冒泡传播。)
例如:
[code]<html>
<body>
<ul>
<li id=”li_1″><button id=”button_1″>Button A</button></li>
<li id=”li_2″><button id=”button_2″>Button B</button></li>
<li id=”li_3″><button id=”button_3″>Button C</button></li>
</ul>
</body>
</html>[/code]
当你单击Button A时,事件经过的路径会向下面这样:
START
| #document \
| HTML |
| BODY } CAPTURE PHASE
| UL |
| LI#li_1 /
| BUTTON <– TARGET PHASE
| LI#li_1 \
| UL |
| BODY } BUBBLING PHASE
| HTML |
v #document /
END
技术部前端开发人员 |
web前端开发技术 储久良 |
web前端开发技术 聂常红 电子书 |
评论前必须登录!
注册