看标题好像非常高大威猛的样子😂,且不要被题目吓到,或许这个技巧很多朋友在工作中都运用过,只是可能不够完善或者不care这种写法属于什么设计模式。
是的,我们的目的很明确,就是DRY——Don't repeat yourself!
文章开头,我们想来点一下题,什么是策略模式?
策略模式的定义:每个策略中定义一系列的算法,把它们一个个封装起来,并且使它们可以相互替换。
好吧,我已开始也是被这个定义吓尿了。简单地举个栗子说,就是你下班回家,可以走路、骑车、坐车、开车、开飞机等,每种方式都是一个策略,在代码里就可以将每个策略写成一个个的方法,方便管理。这样就不用使用一大堆判断语句了,难看而且不好维护。
我们今天讲的是技巧,在这里就不得不说到事件委托——又是一个高大威猛的概念(概念虽好,其实在代码里就很好理解,不信接着看)
没有场景的代码都是耍流氓!


场景很简单,就是点击“已有账号,立即登录”切换到登录,点击“还没有账号”切换到注册
有些小伙伴一下就明白了怎么回事,不就是个点击切换嘛!诶,是滴,就是这么简单,但我们就是喜欢吃猪蹄吃出熊掌的感觉😁
写两个简单的div代替一下(其中class中的hide代表隐藏的css):
<div id="login-box">
这是个登录框
<span id="goToRegister">还没有账号?马上注册</span
</div>
<div id="register-box" class="hide">
这是个注册框
<span id="goToLogin">已有账号,立即登录</span
</div>
善用jQuery的小伙伴们一下子就想到了该怎么写:
$('#goToRegister').click(function () {
$('#login-box').addClass('hide')
.siblings('#register-box').removeClass('hide');
});
$('#goToLogin').click(function () {
$('#register-box').addClass('hide')
.siblings('#login-box').removeClass('hide');
});
不得不佩服jQuery,简单明了。但是这样写有一个很大的问题,就是页面如果有很多的点击事件的时候,难道也要去一个一个复制粘贴类似的代码吗?还是那句话——don't repeat youself!
还记得我们刚才提到过的事件委托吗?还不清楚什么是事件委托还是要去搜一下,简单的理解就是所有子元素的相同事件都委托到父元素。
$('body').on("click",function (e) {
if (e.target.id === 'goToLogin') {
$('#register-box').addClass('hide')
.siblings('#login-box').removeClass('hide');
} else if (e.target.id === 'goToRegister') {
$('#login-box').addClass('hide')
.siblings('#register-box').removeClass('hide');
}
})
是的,这就是事件委托,把两个点击事件都委托给body。为什么要用事件委托呢,一方面是好看(可读性高),不用像上面的代码一样复制那么多的事件代码;另一方面是性能,因为挂载事件的时候是很消耗性能的,一两个事件可能不觉得,一旦有个几十上百个事件(比如说列表)的时候,你就会脸上笑嘻嘻,心里妈卖批。
代码好像稍稍完善了一丢丢,但是!就像上面说的,一旦有很多的而且是不一样子元素的事件的时候,你就要写很多很多判断语句,这是我们万万不想看到的,这个时候我们就要想想有没有什么设计模式来解决此类问题。对,策略模式。
很明显这里有两种策略:跳到登录或者跳到注册
var cutOver = {
goToLogin: function () { //跳到登录
$('#register-box').addClass('hide')
.siblings('#login-box').removeClass('hide');
},
goToRegister: function () { //跳到注册
$('#login-box').addClass('hide')
.siblings('#register-box').removeClass('hide');
}
};
说到策略这个词,我们不得不联想到执行者,那么在这里的执行者是谁呢?我们要写一个去执行策略的方法:
var eventProxy = function (command) {
cutOver[command] && cutOver[command]();
//command存在的时候才执行策略
};
最后就是策略模式的事件委托:
$('body').on("click",function (e) {
eventProxy(e.target.id);
});
写到这里其实就算结束了。慢着!说好的技巧呢?聪明的你会注意到我在策略对象里的方法名其实是两个div的id。所以,最大的技巧既不是策略模式,也不是事件委托,而是这个相当于粘合剂一样的小技巧,是它把策略模式和事件委托很好的联系到一起。