JS中的事件
一:自定义事件
1.使用Event
自定义事件
使用Event接口,可以自定义事件。但是该接口无法在事件传输的同时,传输参数。
var event = new Event('build');
// Listen for the event.
elem.addEventListener('build', function (e) { /* ... */ }, false);
// Dispatch the event.
elem.dispatchEvent(event);
2.使用CustomerEvent
自定义事件
CustomerEvent接口中包含一个detail
字段,同过该字段,可以在事件传播的同时传递参数
var event = new CustomEvent('build', { detail: elem.dataset.time });
function eventHandler(e) {
console.log('The time is: ' + e.detail);
}
3.兼容低版本浏览器
比较老旧的接口,借鉴了Java的写法
// Create the event.
var event = document.createEvent('Event');
// Define that the event name is 'build'.
event.initEvent('build', true, true);
// Listen for the event.
elem.addEventListener('build', function (e) {
// e.target matches elem
}, false);
// target can be any Element or other EventTarget.
elem.dispatchEvent(event);
4.事件冒泡
Event和CustomerEvent 默认为阻止冒泡,如要需要事件冒泡,就需要在构造调用时显式的设置改值为true
const eventAwesome = new CustomEvent('awesome', {bubbles: true});
const evnet = new Event('eventName', {bubbles: true})
实际应用中,如果需要自定义事件从子元素冒泡传递到父元素,可以采用下面的做法
<form>
<textarea></textarea>
</form>
const form = document.querySelector('form');
const textarea = document.querySelector('textarea');
const eventAwesome = new CustomEvent('awesome', {
bubbles: true,
detail: { text: () => textarea.value }
});
// The form element listens for the custom "awesome" event and then consoles the output of the passed text() method
form.addEventListener('awesome', e => console.log(e.detail.text()));
textarea.addEventListener('input', e => e.target.dispatchEvent(eventAwesome));
触发原生事件
可以通过新建与原生事件同名的事件,并且通过JS触发。来模拟原生事件的触发
function simulateClick() {
// 将MouseEvent 换成 Event测试
var event = new MouseEvent('click', {
view: window,
bubbles: true,
cancelable: true
});
var cb = document.getElementById('checkbox');
var cancelled = !cb.dispatchEvent(event);
if (cancelled) {
// A handler called preventDefault.
alert("cancelled");
} else {
// None of the handlers called preventDefault.
alert("not cancelled");
}
}
DOM Level 1 和DOM level 2的区别
事件捕获与事件冒泡
因为浏览器大战的原因,事件的传播有2种方式,冒泡和捕获。随着W3C开始制定标准,2种传播方式都被引进标准。但是默认的传播方式为冒泡的方式。如果想通过捕获的方式监听事件,可以将addEventListener()
的最后一个参数变为 true
事件捕获
- 浏览器检查触发事件的元素的最外层父元素(
<html>
)是否注册有onclick
事件监听。如果有就执行。 - 接着去
<html>
的内部元素做同样的事儿,直到事件的触发元素上截止
事件冒泡
- 浏览器检查触发事件的元素有没有注册响应的事件监听,如果如果注册,就执行。
- 接着向上在父元素上做同样的操作,直到到
<html>
疑问
- 事件初始化时,默认不采用冒泡的方式。那么事件是通过何种方式传播的呢?捕获亦或是已经脱离了文档流。(捕获方式)
- 事件捕获时,如果一个父元素有2个子元素,是2个子元素都会都会做事件注册执行检查呢,还是只给包含触发元素的父元素做事件注册执行检查? (只给包含触发事件的元素的祖、父元素做)
网友评论