再起航,我的学习笔记之JavaScript设计模式28(委托模式)

## 委托模式
### 概念介绍
**委托模式(Entrust): **多个对象接收并处理同一请求,他们将请求委托给另一个对象统一处理请求。
### 利用委托优化循环
如果我们有一个需求需要让用户点击过的列表改变颜色,我们该怎么处理?我想肯定有很多人,和我之前的想法一样
首先我们想要让用户点击过的列表改变颜色,首先我们肯定要获取需要添加点击事件的li标签,然后再去用for循环给每个li添加点击事件让其变颜色,就像下面这样

```
var li=document.getElementsByTagName('li');

for(var i=li.length-1;i>=0;i--){
li[i].onclick=function(){
this.style.backgroundColor='red';
}
}
```
我们看看效果
![](http://images2017.cnblogs.com/blog/774226/201710/774226-20171005224114115-1909998938.gif)

首先我们这样做,想法肯定没错,但是我们这样做无形之中增加了很多点击事件,万一我们这个列表很多,那么内存消耗就会变得很大。那么这个时候我们就可以通过委托模式来简化绑定事件来达到我们的目的

我们知道一个完整的事件流要经过事件捕获、触发事件、事件冒泡三个阶段,那么这个时候我们就可以通过把子元素的事件委托给
父元素去绑定执行,那么我们可以把代码做如下修改

```
var ul=document.getElementById('demo');
ul.onclick=function(e){
var e=e||window.event,
tar=e.target||e.srcElement;
if(tar.nodeName.toLowerCase()==='li'){
tar.style.backgroundColor='yellow';
}
}
```
我们依然可以实现效果
![](http://images2017.cnblogs.com/blog/774226/201710/774226-20171005224124630-2076542924.gif)

我们现在做的就是通过监听ul的点击事件判断目标元素是否是我们需要寻找的元素,如果是则执行相应的操作。这样我们为父元素绑定一个事件,通过委托模式就实现了所有子元素的点击事件需求。达到了我们优化的目的。
### 渲染js生成的元素
通过上面委托模式我们还能针对js中后生成的元素进行渲染添加点击事件
我们想在页面中创建一个DIV然后里面添加一个P标签然后通过js再在这个P标签下增加一个P标签,然后同时为这两个P标签添加点击事件,以前我们如果想要为这种不存在的元素添加点击事件可能是件很麻烦的事情但是有了委托模式之后,我们再实现这个功能我们发现会变得很轻松,我们来看看具体实现
html页面内容
```

我是html里的P标签

```
接着我们再通过js添加一个新的P标签并且给父元素添加点击事件

```
var test=document.getElementById('test');
test.onclick=function(){
var e=e||window.event,
tar=e.target||e.srcElement;
if (tar.nodeName.toLowerCase()==='p') {
tar.innerHTML='我能修改这段文字';
}
}
var p=document.createElement('p');
p.innerHTML='我是js里后来添加的P标签';
test.appendChild(p);
```
我们来看看效果
![](http://images2017.cnblogs.com/blog/774226/201710/774226-20171005224134693-1750199422.gif)

### 优化请求

当然使用委托模式还能优化我们的请求,比如下面我们模拟接收后台的请求去给页面元素赋值
html代码
```

```
如果我们要同时赋值,那么我们通常的做法是请求两次请求不同的方法,达到我们的目的
```
$.get("/Home/Insert", function(res) {
console.log(res);
var json = JSON.parse(res);
$("#test").html(json.Message) ;
});
$.get("/Home/Update", function(res) {
console.log(res);
var json = JSON.parse(res);
$("#test2").html(json.Message);
});
```
![](http://images2017.cnblogs.com/blog/774226/201710/774226-20171005224147786-2083282690.png)

如果模块数量过多,我们这种请求方式,既会造成我们资源的浪费,如果用户网络不好,还会造成漫长的等待,这个时候我们就可以使用委托模式把这些请求打包,委托以另一个对象发送,当得到相应数据时在通过委托对象拆包数据分发给各个方法。

```
var Entrust= {
Insert:function(res) {
console.log(res);
var json = JSON.parse(res);
$("#test").html(json.Message) ;
},
Update:function(res) {
console.log(res);
var json = JSON.parse(res);
$("#test2").html(json.Message) ;
}
}

$.get("/Home/Entrust", function(res) {;
var json = JSON.parse(res);
console.log(json);
Entrust["Insert"] && Entrust["Insert"](json.Insert);
Entrust["Update"] && Entrust["Update"](json.Update);
});
```
好了现在我们就可以通过一个请求完成之前多个请求所要完成的事情,既节省了流量又节省了时间上的开销。
![](http://images2017.cnblogs.com/blog/774226/201710/774226-20171005224157880-705077797.png)

### 总结
委托模式是通过委托者将请求委托给被委托者去处理实现的。因此委托模式解决了请求与委托者之间的耦合。通过被委托者对接收到的请求的处理后,分发给相应的委托者去处理。

**也谢谢大家看到这里:)如果你觉得我的分享还可以请点击推荐,分享给你的朋友让我们一起进步~**

**好了以上就是本次分享的全部内容,本次示例参考自JavaScript设计模式一书,让我们一点点积累一点点成长,希望对大家有所帮助。**

**欢迎转载,转载请注明作者,原文出处。**

上一篇:RPC协议、http协议、https协议的区别


下一篇:[转]Hessian——轻量级远程调用方案