参考书籍:JavaScript设计模式
委托模式(entrust):多个对象接收同一个请求,将请求委托给另一个对象统一处理
事件流:捕获,触发,冒泡
事件冒泡:子元素的事件委托给更高层上的父元素去绑定执行。
例1:点击日历格子,其对应格子背景变为灰色—>优化事件数量
ul.onclick = function (e) {
var e = e || window.event,
tar = e.target || e.srcElement;
if (tar.nodeName.toLowerCase() === 'li') {
tar.style.backgroundColor = 'grey';
}
}
例2: 预言未来,在下面div中,p 元素的click事件很容易获取,但是假如未来添加一行文字,新添加的事件就很难直接实现,不过可以用事件冒泡,将事件转化成父元素的绑定事件。
<div id="article">
<p>已存在的文字</p>
</div>
var article = document.getElementById('article');
article.onclick = function (e) {
var e = e || window.event,
tar = e.target || e.srcElement;
if (tar.nodeName.toLowerCase() === 'p') {
tar.innerHTML = '修改这段内容';
}
}
var p = document.createElement('p');
p.innerHTML = '新增加内容';
article.appendChild(p);
例3 内存外泄
下面的例子中,id为btn的元素绑定点击事件,在触发时,对其父元素中的内容进行了重置,这样将会将按钮自身覆盖掉,然而g变量保存的元素绑定的click 事件没有清除,所以这个事件就会泄露到内存中。
var g = function (id) {
return document.getElementById(id);
}
g('btn').onclick=function(){
g('btn_container').innerHTML = '触发事件';
}
修改后
g('btn_container').onclick = function (e) {
var tar = e && e.target || window.event.srcElement;
if (tar.id === 'btn') {
g('btn_container').innerHTML = '触发事件';
}
委托事假还可以做数据分发,比如我们页面有很多模块,都需要向后端发起请求以获取数据
通常做法
$.get("./deal?q=banner",function(res){
//处理banner模块逻辑
})
$.get("./deal?q=aside",function(res){
//处理aside模块逻辑
})
$.get("./deal?q=article",function(res){
//处理article模块逻辑
})
$.get("./deal?q=message",function(res){
//处理message模块逻辑
})
这样做,我们会向服务器发送5次请求,即是对资源的浪费,又会造成漫长的等待。这时我们就可以将这些请求打包,委托给另一个对象发送,当得到响应数据时再通过委托对象拆包数据分发给各个模块
var Deal = {
banner: function (res) {
//处理banner模块逻辑
},
aside: function (res) {
//处理aside模块逻辑
},
article: function (res) {
//处理article模块逻辑
},
message: function (res) {
//处理message模块逻辑
}
}
$.get("./deal?", function (res) {
for (var i in res) {
Deal[i] && Deal[i](res[i]);
}
})