javaScript中代理模式详解

作为我学习设计模式的开端,今天总结一下JavaScript的代理模式。
代理模式是JavaScript中最常出现的设计模式,因为在JavaScript中的表现非常直接,方便。

我们来举个栗子。

<ul id="parent-list">
<li id="child-0">Item 0</li>
<li id="child-1">Item 1</li>
<li id="child-2">Item 2</li>
<li id="child-3">Item 3</li>
<li id="child-4">Item 4</li>
<li id="child-5">Item 5</li>
<li id="child-6">Item 6</li>
</ul>

我们现在有这么一个列表,我们需要在用户点击li标签的时候做出响应。你可能会给每个li标签绑定事件。

for(var i = 0; i <=6; i++) {
document.getElementById('child-' + i).addEventListener('click', function() {
//做爱做的事
});
}

当然你可能是用更高级的写法来降低耦合度,比如:

var list = document.getElementById('parent-list');
var listItems = list.getElementsByTagName('li');
var listLength = list.length;
for(var i = 0; i < listLength; i++) {
var listItem = listItems[i];
listItem.onclick = function() {
//做爱做的事
}
}

且不说闭包可能带来的问题,这样写是没错,除非…

假设现在我们需要频繁动态增删改li标签,那么相应的增加删除事件监听将会是个噩梦。更好的解决方式是使用代理模式,把所有li标签上的事件监听全都转移到一个公共元素上,然后通过某种标记判断当前事件来源即可。

那么,去哪里找这么一个公共元素呢?
我们可以使用他们的最小公父亲(我瞎说的)#parent-list,我们都知道js事件有捕获和冒泡两个过程。
jsEvent
当你点击了目标对象,事件会通过冒泡逐层向外传递,并且事件对象中保存着目标对象的副本,所以使用事件代理,我们可以通过处理事件对象简单地判断事件来源。

修改我们的代码:

document.getElementById("parent-list").addEventListener("click", function(e) {
if(e.target && e.target.tagName.toLowerCase() == "li") {
console.log("List item ", e.target.id.replace("child-"), " was clicked!");
}
});

总结

优势:

  • 大量减少了绑定事件的数量,代码执行效率更高!
  • DOM结构更改,不需要重新绑定事件

劣势:

  • javaScript中部分事件并没有冒泡,比如blur,focus
  • 代理的代码也可能会非常耗时,所以最好保持事件处理的代码尽量简洁

相关资源

[Event delegation]
—— 事件代理常用情景

[How JavaScript Event Delegation Works]
—— JavaScript事件代理

[JavaScript学习总结(九)事件详解]
—— 来自SegmentFault

如需转载,请注明出处:http://w3ctrain.com/2015/10/14/javascript-event-delegation/

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值