本文讲解事件的绑定,触发,删除及NodeList对象对addEventListener方法的扩展。
提示:以下JS示例中所使用的DOM节点均来源于百度首页的DOM结构。如果需要测试,可以打开百度首页,将代码粘入控制台执行即可。
一.绑定事件(以下示例可以打开百度首页进行测试)
1.通过HTML属性,EX:
<button onclick="alert('this is button')">
这种方式简单粗暴,不推荐使用。
2.通过DOM元素属性,EX:
document.querySelector('#kw').onclick = function(){
alert('点击事件被执行了');
}
但是通过这种方式绑定的事件,多次绑定后会存在覆盖。EX:
document.querySelector('#kw').onclick = function(){
alert('我又进行了一次绑定');
}
通过两次绑定,触发时仅会执行最后一次的事件绑定,效果并如下图所示:
如果同时存在通过HTML属性绑定的事件时,通过DOM元素属性绑定的事件会覆盖通过HTML属性绑定的事件。
通过代码进行触发onclick事件方式:
document.querySelector('#kw').onclick()
//也可以通过进行触发
document.querySelector('#kw').click()
这两种方式区别虽然都触发了事件函数,但是通过onclick()与click()存在本质上的区别,click()是真实的触发了鼠标点击事件,而onclick只不过是调用了当前DOM对象上所绑定的onclick函数。通过下面的这个示例可以看出通过onclick()调用事件函数后并未生成window.event对象,这以足以说明当前事件并未触发。EX:
document.querySelector('#kw').onclick = function(e){
console.log(e);
};
// onclick()
document.querySelector('#kw').onclick(); // => undefined
// click()
document.querySelector('#kw').click(); // => [Object MouseEvent]
这里需要特殊说明的是,除了onclick事件可以通过click()方法进行事件触发外,其它事件并不能通过代码的方式进行触发。EX:
document.querySelector('#kw').onresize = function(){
alert('onresize');
}
document.querySelector('#kw').resize(); // => TypeError: document.querySelector(...).resize is not a function
3.通过EventTarget事件接口:
EventTarget可以为document、Element、XMLHttpRequest 其它待补充?
语法:
EventTarget.addEventListener(type, listener, options, useCapture);
-
type: 表示监听事件类型的字符串
-
listener: 事件监听函数
-
options: 事件监听函数配置参数
-
options.capture: 是否捕获冒泡
-
options.once: 是否仅执行一次
-
options.passive: 是否永远不会调用 preventDefault()
useCapture: 指定事件是否在捕获或冒泡阶段执行.true - 事件句柄在捕获阶段执行 false- 默认。事件句柄在冒泡阶段执行
EX:
document.querySelector('#kw').addEventListener('click', function(){
console.log('addEventListener click');
}, false);
二.触发事件[trigger]
无论是通过DOM元素属性还是通过EvnetTarget事件接口绑定的事件,除了click可以直接通过.click()方法触发事件外。其它的事件如何通过代码来触发?
1.通过document对象
var event = document.createEvent('HTMLEvents'); // 通过文档对象 document 的createEvent()方法创建新的 Event 对象。
event.initEvent('click', true, true); //执行initEvent初始化事件对象类型。
document.querySelector('#kw').dispatchEvent(event); //触发click事件, 执行后返回用于标识执行是否成功的boolean值
// EX: mousedown事件绑定及执行
document.querySelector('#kw').addEventListener('mousedown', function(e){
console.log(e); // => Event{type: "mousedown", ...}
});
var event = document.createEvent('HTMLEvents');
event.initEvent('mousedown', true, true);
document.querySelector('#kw').dispatchEvent(event); // => true
createEvent实际上不是由 Document 接口定义的,而是由 DocumentEvent 接口定义的。只要支持 Event 模块,那么 Document 对象就会实现 DocumentEvent 接口并支持该方法。
2.通过Event对象
var myEvent = new Event('click'); //实例出类型为click的事件对象
document.getElementById('kw').dispatchEvent(myEvent); //触发click事件, 执行后返回用于标识执行是否成功的boolean值
EX: mousedown事件绑定及执行
document.querySelector('#kw').addEventListener('mousedown', function(e){
console.log(e); // => Event{type: "mousedown", ...}
});
var myEvent = new Event('mousedown');
document.getElementById('kw').dispatchEvent(myEvent); // => true
这两种方式实现效果完全相同,通过两种不同的方式生成 Event 对象实例,然后执行dispatchEvent()方法进行事件触发。
相比较而言第二种方式使用更加合理,且由于第一种方式已经从web标准中删除,所以推荐使用第二种方式。
**相关键接: **
createEvent已从Web标准中删除
initEvent已从Web标准中删除
三.删除事件
1.删除通过HTML属性增加的事件,EX:
<button onclick="alert('this is button')">
document.querySelector('#kw').onclick = null;
2.删除通过DOM元素属性增加的事件,EX:
document.querySelector('#kw').onclick = function(){
alert('点击事件被执行了');
}
document.querySelector('#kw').onclick = null;
3.通过addEventListener增加的事件,EX:
var eventCall = function(){
console.log('addEventListener click');
};
document.querySelector('#kw').addEventListener('click', eventCall, false);
document.querySelector('#kw').removeEventListener('click', eventCall);
四.NodeList扩展addEventListener
NodeList.prototype.addEventListener = function(type, listener){
[].forEach.call(this, function(v, i){
v.addEventListener(type, listener);
})
};
document.querySelectorAll('div').addEventListener('click', function(e){
console.log(e)
});
如果想详细了解Event,请查阅发布于github jTool类库下的 Event 对象。
@拭目以待
个人站点:www.lovejavascript.com
表格管理插件:gridmanager.lovejavascript.com && github地址
QQ交流群 (452781895):How To Make Love
网友评论