简单使用
addEventListener
添加监听事件函数,有三个参数
- 第一个参数:监听动作(必须)
- 第二个参数:触发函数(必须)
- 第三个参数:一个bool类型。当为
false
时为冒泡获取(由里向外),true
为capture方式(由外向里)。(可选)
关于第三个参数为事件冒泡方式,不在本文说明范围之内!
removeEventListener
移除解绑监听事件函数,有两个参数。
- 第一个参数:监听动作(必须)
- 第二个参数:绑定动作指定的函数体(必须)
实例1,直接在参数内传入一个匿名函数体:
element.addEventListener('click', function () {
alert('Hello word!');
});
这种方式最简便,但不能解绑监听动作,如以下代码是无效的:
// 这种解绑方式是无效的
element.removeEventListener('click', function () {
alert('Hello word!');
});
实例2,传入函数变量
var handle = function () {
alert('Hello word!');
};
element.addEventListener('click', handle);
如果要解绑监听事件很容易,如下:
element.removeEventListener('click', handle);
复杂应用
然而实际业务需要还是复杂的很多,仍然需要我们精心设计。
var main = function () {
// 获取节点
var button = document.querySelectorAll('button');
// 获取一个随机数
var rand = Math.random();
// 单击处理函数
var clickHandle = function () {
console.log(rand);
};
// 添加单击事件
button[0].addEventListener('click', clickHandle);
};
window.onload = main;
以上代码是一个很普通的业务,处理函数体内能访问到rand变量是因为处理函数clickHandle
是在main函数里声明的。假如处理函数来自别处,如:
// 单击处理函数
var clickHandle = function () {
// rand访问不到
console.log(rand);
};
var main = function () {
// 获取节点
var button = document.querySelectorAll('button');
// 获取一个随机数
var rand = Math.random();
// 添加单击事件
button[0].addEventListener('click', clickHandle);
};
这样rand就访问不到了,所以对于addEventListener
里的函数体如何传参数呢?我们可以这样做:
// 单击处理函数
var clickHandle = function (rand) {
return function(){
console.log(rand);
};
};
var main = function(){
// 获取节点
var button = document.querySelectorAll('button');
// 获取一个随机数
var rand = Math.random();
// 添加单击事件 把rand传入
button[0].addEventListener('click', clickHandle(rand));
};
window.onload = main;
clickHandle
先接收参数,然后再return一个匿名函数,这样就解决了addEventListener
函数体传参的问题,然而上面的方案并不是很完美,因为不能解绑
// 虽然传入的参数相同,返回的函数也一样,但这样是无效的操作
button[0].removeEventListener('click', clickHandle(rand));
因为JavaScript不能像Python能打出ID值,但我觉得removeEventListener
解绑时,会根据传入函数变量的内存指向地址去搜寻addEventListener
时传入函数的内存地址是否匹配,如果匹配就可以执行解绑操作。比如下面这个DEMO就很好的说明了这个问题:
index.html
<button>alert</button>
app.js
var main = function(){
// 获取节点
var button = document.querySelectorAll('button');
var handle1 = function () {
console.log('handle1');
};
var handle2 = function () {
console.log('handle2');
};
button[0].addEventListener('click', handle1);
button[0].addEventListener('click', handle2);
};
给button添加了两个click事件,分别对应不同的handle,单击button后,会分别打出出handle1与handle2。此时,我们可以通过以下代码解绑其中一个监听事件,但不会影响其它事件的监听
// 移除handle1的监听
button[0].removeEventListener('click', handle1);
因此回来看刚才的例子,完美解决方案的应该是这样:
// 单击处理函数
var clickHandle = function (rand) {
return function(){
console.log(rand);
};
};
var main = function(){
// 获取节点
var button = document.querySelectorAll('button');
// 获取一个随机数
var rand = Math.random();
// 获得匿名函数
var handle = clickHandle(rand);
// 添加单击事件 把rand传入
button[0].addEventListener('click', handle);
// 移除绑定事件
button[0].removeEventListener('click', handle);
};
window.onload = main;
没有一个API能查出一个节点被添加了哪些事件,这是一个问题,只能通过代码设计解决!