今天忽然要維護一個老古董的項目,裏面大部分都是原生js和jquery,用vue之類多了,這些都有些生疏... 代碼中有一個HTML事件處理程序,<button onclick="clickHandler(e)">屠龍寶刀點擊就送</button>
javascript
function clickHandler(e) { console.log(e.target); }
剛開始都沒注意有啥錯,而後在函數中e.target
等都會報錯:ReferenceError: e is not defined
vue
很明顯,傳入的事件對象參數是錯誤的,在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
了。瀏覽器
仍然用上面的聲明函數:閉包
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級事件處理程序了: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.target
和event.currentTarget
既然都寫了事件處理程序順便再複習下這兩個的區別,target
是事件的實際目標,currentTarget
是處理事件的元素,也就是綁定事件函數的元素,事件處理函數中this
的值等於currentTarget
。