js event 使用讲解

event,事件,js

拭目以待 发布于

本文讲解事件的绑定,触发,删除及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);


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 对象。