前言
js进行事件处理的写法非常重要, 好的写法可以使代码松耦合, 从而容易维护和测试. 下面我们通过改写一个实际案例来探讨如何绑定事件处理函数.
案例分析
坏的写法
function handleClick(event){
var popup = document.getElementById('popup');
popup.style.left = event.clientX + 'px';
popup.style.top = event.clientY + 'px';
popup.className = 'reveal';
addListener(element,'click',handleClick)
}
改进一
分析: 上段代卖的第一个问题是事件处理程序包含了应用逻辑. 应用逻辑是和应用相关的功能性代码, 而不是用户行为相关的. 应用逻辑从所有事件处理程序中抽离出来的做法是一种最佳实践, 这样做有两个好处. 1,一个应用逻辑能对应多个事件处理,避免代码重复. 2, 可以对应用逻辑进行单独测试.
var MyApplication = {
//事件处理
handleClick: function(event){
this.showPopup(event)
},
//应用逻辑
showPopup: function(event){
var popup = document.getElementById('popup')
popup.style.left = event.clientX + 'px'
popup.style.top = event.clientY + 'px';
popup.className = 'reveal';
}
}
addListener(element,'click',function(event){
MyApplication.handleClick(event)
})
改进二
分析: 上面这段代码已经很好了, 但是还有不足之处, 那就是应用逻辑依赖于事件对象. 这样做有两个坏处, 1, 好的API对于接收的参数是清晰明确的, 将event对象作为参数非常含糊, 不能告诉你event的哪些属性是需要用到的. 2. 不利于测试, 当你需要进行测试时, 必须构建要给event对象传递给应用逻辑.(www.hedaoshe.com)
最佳实践: 让事件处理程序使用event对象来处理事件, 然后拿到所有需要的数据传给应用逻辑. 最好是只让事件处理程序接触event对象, 并做事件相关的操作. 包括阻止默认事件火阻止事件冒泡等.
var MyApplication = {
//事件处理程序是唯一接触event对象,并进行事件相关操作
handleClick: function(event){
//加入事件的额外操作
event.preventDefault()
event.stopPropagation()
this.showPopup(event.clientX,event.clientY)
},
//应用逻辑的参数要明确,进一步解耦
showPopup: function(x,y){
var popup = document.getElementById('popup')
popup.style.left = x + 'px'
popup.style.top = y + 'px';
popup.className = 'reveal';
}
}
addListener(element,'click',function(event){
MyApplication.handleClick(event)
})
结尾
改进二后的成型代码就是我们需要的最佳实践, 如果能坚持这样写, 可以更好的维护代码和测试. 奥利干!!!