美文网首页
JS中的事件

JS中的事件

作者: XimingWang | 来源:发表于2018-07-20 14:24 被阅读16次

    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>
    image.png

    疑问

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

    参考

    相关文章

      网友评论

          本文标题:JS中的事件

          本文链接:https://www.haomeiwen.com/subject/adowpftx.html