本文主要记录《编写可维护的JavaScript》一书中关于事件处理的一些编程技巧。加深自己的理解,应用到实际项目中。
事件处理在js中非常重要。所有js均通过事件处理来绑定到UI上。
反面实例
1 | function handleClick(event){ |
事件处理程序还包含了应用逻辑。应用逻辑是和应用相关的功能性代码,而不是和某一个用户行为完全相关的。
如上例,是点击某个元素,根据点击位置来显示目标元素。但有可能,同时有其他用户行为来,显示目标元素(例如,点击其他元素或,鼠标移入某个元素)。存在多个用户行为来显示目标元素的话,就要复制相同的代码。
第一步:隔离应用逻辑
将上例代码中的应用逻辑,隔离出来1
2
3
4
5
6
7
8
9
10
11
12
13
14var 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.calssName = 'show';
}
}
addListener(element,'click',function(event){
myApplication.handleClick(event);
}); // 此处为封装的兼容性事件监听函数
应用逻辑全部转到myApplication.showPopup方法中,事件处理程序myApplication.handleClick只负责触发应用逻辑。
第二步:不分发事件对象
应用逻辑不应依赖于event事件对象。
原因:
- 透明清晰的API
- 便于测试
上例代码中,应用逻辑代码只使用了事件对象的clientX和clientY属性。1
2
3
4
5
6
7
8
9
10
11
12
13
14var myApplication = {
handleClick = function(event){
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.calssName = 'show';
}
}
addListener(element,'click',function(event){
myApplication.handleClick(event);
}); // 此处为封装的兼容性事件监听函数
myApplication.handleClick方法,将x坐标和y坐标传入myApplication.showPopup方法中,可以很清晰的看到myApplication.showPopup方法希望传入的参数。
事件处理程序和阻止默认事件、阻止事件冒泡
事件处理程序,应在进入应用逻辑之前,针对event对象做任何必要的操作,包括阻止默认事件和阻止事件冒泡1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16var myApplication = {
handleClick = function(event){
event.stopPropagation();
event.preventDefault();
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.calssName = 'show';
}
}
addListener(element,'click',function(event){
myApplication.handleClick(event);
}); // 此处为封装的兼容性事件监听函数