JS中的事件

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})

实际应用中,如果需要自定义事件从子元素冒泡传递到父元素,可以采用下面的做法

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

事件捕获

  • 浏览器检查触发事件的元素的最外层父元素()是否注册有onclick事件监听。如果有就执行。
  • 接着去的内部元素做同样的事儿,直到事件的触发元素上截止

事件冒泡

  • 浏览器检查触发事件的元素有没有注册响应的事件监听,如果如果注册,就执行。
  • 接着向上在父元素上做同样的操作,直到到
JS中的事件_第1张图片
image.png

疑问

  • 事件初始化时,默认不采用冒泡的方式。那么事件是通过何种方式传播的呢?捕获亦或是已经脱离了文档流。(捕获方式)
  • 事件捕获时,如果一个父元素有2个子元素,是2个子元素都会都会做事件注册执行检查呢,还是只给包含触发元素的父元素做事件注册执行检查? (只给包含触发事件的元素的祖、父元素做)

参考

  • Creating and triggering events - Developer guides | MDN
  • Event() - Web APIs | MDN 解释了参数 bubbles的来源
  • CustomEvent() - Web APIs | MDN 解释了参数detail
  • MouseEvent() - Web APIs | MDN解释了参数 view
  • Introduction to events - Learn web development | MDN

你可能感兴趣的:(JS中的事件)