DOM事件監聽和觸發


EventTargetAPI定義了DOM事件(mouse事件等)的監聽和觸發方法,所有的DOM節點都部署了這個接口。

這個接口有三個方法:addEventListener, removeEventListener, dispatchEvent。

一. EventTargetAPI

1. EventTarget.addEventListener(type, listener, options)

給DOM節點對象添加事件監聽。

語法:

eleTarget.addEventListener(type, listener [, useCapture])
// type: DOM事件類型,區分大小寫
// listener: 監聽回調函數,function(e){}; e是事件發生產生的Event對象;
// userCapture: 布爾值,是否在捕獲階段觸發;相當於{capture: boolean}

第二個參數,是個回調函數,入參是Event對象,內部的this, 指向DOM節點對象eleTarget.

  <button id="btn">ClickMe</button>
  <script>
    btn.addEventListener('click',function(e) {
      console.log(this === btn); // true
    })
  </script>

第三個參數還可以是一個配置對象:

eleTarget.addEventListener(type, listener, options)
// options的屬性如下:
options = {
   capture: boolean, // 是否在捕獲階段觸發;默認false
   once: boolean, // 是否只監聽一次,然后自動移除;默認false,
   passive: boolean, // 是否禁止prentDefault()方法;默認false
}

為同一個目標添加同一個監聽事件,如果回調函數相同,那么只執行一次,其余的忽略。

function hello() {
  console.log('Hello world');
}

document.addEventListener('click', hello, false);
document.addEventListener('click', hello, false); //自動忽略
// 運行結果
hello world

為同一個目標添加同一個監聽事件,如果回調函數不同,那么按照添加順序,依次執行。

function hello() {
  console.log('Hello');
}
function world() {
  console.log('world')
}
document.addEventListener('click', hello, false);
document.addEventListener('click', world, false); 
// 運行結果
hello
world

這點和DOM對象的on[event]事件不同,on[Event]會出現覆蓋,只最后一個起作用;

而且只在冒泡階段觸發,不能指定觸發的階段。

function hello() {
  console.log('Hello');
}
function world() {
  console.log('world')
}
document.onclick = hello;
document.onclick = world;
// 運行結果
world

另外,HTML的on[event]事件,引號內是可執行JS代碼

<div onclick="hello()">ClickMe</div>

2. EventTarget.removeEventListener(type, listener, options)

語法:

function hello() {
   console.log("hello");
}
element.addEventListener('click', hello, true);
element.removeEventListener('click', hello, true);
//注意
// remove方法作用的element和后面的參數必須完全一致。
// 且第二個參數必須是函數的變量形式傳遞;否則,相當於一個新的函數,即使內容和add中一樣,也是一個新的函數

3. EventTarget.dispatch(event)

手動觸發監聽函數,通過代碼觸發;

參數不能為空,必須是Event對象;

返回一個布爾值,表示是否觸發成功;  返回值在監聽函數執行完成后返回。

示例:

  btn.addEventListener('click',function(event) {
    console.log('listener end')
  })
  console.log(btn.dispatchEvent(new Event('click')));
 // 運行結果如下:
 listener end
 true

應用: 

可以自定義一個事件監聽函數,在需要的位置觸發函數調用。

  btn.addEventListener('lyra',function(event) {
    console.log('Be dispatched at i=2')
  })
  btn.addEventListener('myevent',function(event) {
    console.log('Be dispatched at i=1')
  })
  for(let i=0; i < 10; i++) {
    if (i === 1) {
      btn.dispatchEvent(new Event('myevent'));
    }
    if (i === 2) {
      btn.dispatchEvent(new Event('lyra'));
    }
  }
  // 運行結果
  Be dispatched at i=1 //i===1時先觸發myevent
  Be dispatched at i=2

二. Event事件

上面的監聽和觸發函數的基礎是Event對象。

Event是js的原生對象,每個DOM事件產生的對象都是它的實例。

它是一個構造函數,實例化可以自定義一個事件。

語法如下:

const event = new Event(type, options);
// type是自定義事件的類型
// options是自定義事件的配置

options有兩個屬性:

const options = {
  bubbles: boolean, // 指定事件是否可以冒泡;默認false,只在捕獲階段觸發
  cancelable: boolean, // 指定事件是否可以調用preventDefault()方法
}

三. CustomEvent事件

和Event事件的構造函數的區別是: 觸發時可以通過detail屬性傳入自定義數據。

const data = fetch(url);
const event = new CustomEvent('myevent', {
   bubbles: false,
   cancelable: false,
   detail: data
})
ele.addEventListener('myevent', function(e){
   console.log(e.detail); //data
})
ele.dispatch(event)

四.應用

DOM節點同時綁定單擊事件和雙擊事件

let previous=0;
let timer;
btn.addEventListener('click', function(e) {
  const diff = e.timeStamp - previous;
  if (diff < 300) {// 雙擊
    console.log('double click');
    clearTimeout(timer);
  } else {
    timer = setTimeout(function() {
      console.log('single click')
    },300);
    previous = e.timeStamp;    
  }
},false);

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM