事件處理程序中event參數的傳遞

問題

今天忽然要維護一個老古董的項目,裏面大部分都是原生js和jquery,用vue之類多了,這些都有些生疏... 代碼中有一個HTML事件處理程序,<button onclick="clickHandler(e)">屠龍寶刀點擊就送</button>javascript

function clickHandler(e) {
  console.log(e.target);
}

剛開始都沒注意有啥錯,而後在函數中e.target等都會報錯:ReferenceError: e is not definedvue

很明顯,傳入的事件對象參數是錯誤的,在HTML事件處理程序的狀況下正確的作法是傳入完整的event名稱,<button onclick="clickHandler(event)">屠龍寶刀點擊就送</button>java

其實event能夠看做是window.event的簡寫,用window對象的其餘屬性試驗下就能夠發現,好比用location<button onclick="clickHandler(location)">屠龍寶刀點擊就送</button>, 那麼函數中e.href便可打印出當前連接。jquery

function clickHandler(e) {
  console.log(e.href);
}

思考

其實上面原本不是個問題,主要平時不多用行內的HTML事件處理程序,因此隨手把參數event寫錯爲了e。在DOM0和DOM2級事件處理程序中,瀏覽器都會將一個event對象傳入到事件處理程序中,這種用js指定的事件處理程序的形參固然能夠隨便命名了,通常簡寫爲e了。瀏覽器

DOM0

仍然用上面的聲明函數:閉包

function clickHandler(e) {
  console.log(e.target);
}
document.getElementsByTagName('button')[0].onclick = clickHandler;

準確的打印出了button元素。dom

其實還能夠將事件處理函數定義爲無參函數,能夠用arguments來獲取事件對象。函數

function clickHandler1() { //無參處理函數
  var e = arguments[0];
  console.log(e.target);
}

DOM2

最經常使用的就是dom2級事件處理程序了:this

document.getElementsByTagName('button')[0].addEventListener('click', clickHandler, false );

一樣也可使用無參函數.net

document.getElementsByTagName('button')[0].addEventListener('click', clickHandler1, false );

匿名函數時候須要注意的

DOM1和2級事件處理程序也經常使用匿名函數的方式:

document.getElementsByTagName('button')[0].onclick = (e) => {
  console.log(e.target);
}

這樣傳入event參數的有參匿名函數是沒有問題的,可是若是用無參函數的話下面代碼就會報錯出問題:

document.getElementsByTagName('button')[0].onclick = () => {
  var e = arguments[0];
  console.log(e.target);
}

根據MDN上描述,arguments不能使用箭頭函數,由於箭頭函數沒有本身的this,使用的是封閉執行做用域的this。
可是若非要使用arguments的話能夠傳入...args:

document.getElementsByTagName('button')[0].onclick = (...args) => {
  var e = args[0];
  console.log(e.target);
}

事件處理程序傳遞多個參數

在最先的HTML事件處理程序中咱們能夠直接傳入多個參數,

<button onclick="clickHandler(event, 'a', 'b')">屠龍寶刀點擊就送</button>

可是DOM0和2級事件處理程序默認只傳入event參數,能夠採用閉包的方法(IIFE)來處理:

document.getElementsByTagName('button')[0].addEventListener('click', (function(a, b) {
    return function(e) {clickHandler(e, a, b); };
}) ('a', 'b'), false);

event.targetevent.currentTarget

既然都寫了事件處理程序順便再複習下這兩個的區別,target是事件的實際目標,currentTarget是處理事件的元素,也就是綁定事件函數的元素,事件處理函數中this的值等於currentTarget

在線演示

在線demo

參考資料

相關文章
相關標籤/搜索