摘要:推薦使用該方式進行事件的注冊,可以對同一節(jié)點注冊多個事件處理函數(shù)。當前冒泡流是被大多瀏覽器支持,因此大多賦為。阻斷事件的冒泡流或者事件捕獲流。資料推薦紅寶書阮一峰事件模型
一步,一步前進の一步
事件是文檔或者瀏覽器窗口中發(fā)生的一些交互瞬間。JS注冊事件處理程序來預訂事件,當事件發(fā)生的瞬間來執(zhí)行相應的代碼,進而實現(xiàn) JS 和 HTML(即文檔或者瀏覽器窗口) 的交互。
事件流事件流描述的是從頁面中接收事件的順序。
用手指戳一下屏幕上的同心圓的中心,先點到的是最外圍的大圓,還是最核心的小圓呢?這個就是事件流要處理的本質問題。早起的 IE 和 Netscape 對此有不同的觀點,IE認為先點到的是最小的圓,然后在一層層的傳遞到最外面的大圓(事件冒泡),Netscape 正好相反,最先碰到的是最外圍的大圓,然后在一層層的追蹤到最精準的小圓(事件捕獲)。
事件冒泡:事件開始由最具體的元素接收,然后逐級向上傳播到較為不具體的節(jié)點。
事件捕獲:事件是從不太具體的節(jié)點開始產(chǎn)生接收,而最具體的節(jié)點應該是最后接收事件的。
事件流規(guī)范出來說,事件傳遞有三個階段: 捕獲階段、目標階段、冒泡階段。
瀏覽器的事件處理大概就是注冊、監(jiān)聽。程序開始就對未來會發(fā)生的某些事情,做出預期,對預期做出正確的反應。事件處理程序就是被注冊的正確反應,監(jiān)聽這個操作由瀏覽器自己完成。
瀏覽器提供了三種方法,為事件綁定監(jiān)聽函數(shù)。
需要注意的是:此處的事件處理程序是需要帶小括號的,大概的過程是當 div 接收到事件時,會將onclick后面的代碼原封不動的傳入JavaScript引擎執(zhí)行,不加小括號就不會觸發(fā)處理程序。
此方式會讓 js 的代碼和 html 代碼雜糅在一起,不易代碼的變更和維護,因此不推薦使用。
Dom 0級事件注冊div.onclick = function (event) { console.log("觸發(fā)事件"); };以元素節(jié)點對象的事件屬性的方式進行注冊,與第一種方式類似。
Dom 2級事件注冊
該事件只會在冒泡階段觸發(fā)。target.addEventListener(type, listener[, useCapture])
type事件名稱,大小寫敏感;listener處理函數(shù);useCapture是否在捕獲階段觸發(fā)。
推薦使用該方式進行事件的注冊,可以對同一節(jié)點注冊多個事件處理函數(shù)。當前冒泡流是被大多瀏覽器支持,因此useCapture大多賦為false。document.addEventListener("click", hello, false); document.addEventListener("click", hello2, false);IE 事件處理程序早期的 IE 瀏覽器只支持冒泡流,有自己的事件注冊和移除的方法:attachEvent()、detachEvent()
btn.attachEvent("onclick", function () { alert("ie browser"); });需要注意的是處理函數(shù)的 this 是指向 window 的,而不像前兩種事件處理函數(shù)的 this 會指向事件所在的 dom 節(jié)點對象。
跨瀏覽器事件處理程序紅寶書方案代碼如下:
var EventUtil = { addHandler: function(elm, type, handler) { if (elm.addEventListener) { elm.addEventListener(type, handler, false); } else if (elm.attachEvent) { elm.attachEvent("on" + type, handler); } else { elm["on" + type] = handler; } } };該方法是比較好的,但是處理函數(shù)執(zhí)行時的 this 指向還是有一點點問題,attachEvent方式還是指向 window 的,如果想更加完善,請參考 js 忍者秘籍上面的方案。
在處理事件時,我們需要考慮一些性能的問題,有必要限制事件處理函數(shù)的數(shù)量,適當?shù)臅r候將已有的事件處理程序移除掉或者采用事件委托機制減少注冊的個數(shù)。下面我們簡單談談如何移除事件處理程序。
var EventUtil = { removeHandler: function (elm, type, handler) { if (elm.removeEventListener) { elm.removeEventListener(type, handler, false); } else if (elm.detachEvent) { elm.detachEvent("on" + type, handle); } else { elm["on" + type] = handler; } } }事件的移除有個原則,怎么注冊的就要原封不動的 copy 參數(shù)調(diào)用移除。此處需要注意的是當你的事件處理函數(shù)是匿名函數(shù)時,那將會永遠也清理不掉了。
this 指向處理函數(shù)執(zhí)行時,this 指向現(xiàn)代的瀏覽器指向的是 事件所在dom 節(jié)點,老 IE 指向window。
事件對象事件發(fā)生后,會產(chǎn)生一個事件對象,作為參數(shù)傳給監(jiān)聽函數(shù)。事件有若干的實例屬性和實例方法。只講下筆者認為重要的currentTarget、target、preventDefault()、.stopPropagation()、stopImmediatePropagation()。
currentTarget事件處理函數(shù)注冊在什么節(jié)點上,那么 currentTarget 就永遠的指向了該節(jié)點。
target,我們回顧一下事件流的概念,事件會經(jīng)歷捕獲階段、目標階段、冒泡階段,可以感覺到事件的傳遞畫了個對稱的鉤,target 表示事件當前所處的節(jié)點位置。
我們不僅可以讀取事件的狀態(tài),還可以人為的改變它的內(nèi)部狀態(tài)。preventDefault()阻止事件的默認行為,如 a 標簽被點擊時就會跳轉到新的 url,我們可以使用event.preventDefault()來阻止跳轉。
stopPropagation()阻斷事件的冒泡流或者事件捕獲流。但如果同一節(jié)點上注冊了多個事件處理程序,那么該節(jié)點上的事件處理程序會繼續(xù)處理,它只會阻斷事件向上或向下的傳播。
stopImmediatePropagation()更為狠毒,事件會停止在該事件處理程序上,同節(jié)點的其他事件處理程序也不會被觸發(fā)了。
事件代理由于事件會在冒泡階段向上傳播到父節(jié)點,因此可以把子節(jié)點的監(jiān)聽函數(shù)定義在父節(jié)點上,由父節(jié)點的監(jiān)聽函數(shù)統(tǒng)一處理多個子元素的事件。這種方法叫做事件的代理(delegation)。
- test
- test
- test
- test
- test
...假設業(yè)務需要給 li 添加 click 監(jiān)聽事件,那么初學者可能會采用直接獲取 li 節(jié)點的方式進行事件程序的綁定,那么有幾個 li,就需要注冊多少個事件處理程序。可以采用事件代理機制實現(xiàn)性能優(yōu)化,代碼如下:
var ul = document.querySelector("ul"); ul.addEventListener("click", function (event) { if (event.target.tagName.toLowerCase() === "li") { // some code } });事件代理和事件委托是同一個東西,主要是利用事件冒泡和事件的實例屬性 target,目的是減少事件處理程序的數(shù)量,提高性能。
資料推薦紅寶書
阮一峰 事件模型
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/97039.html
摘要:異步任務必須指定回調(diào)函數(shù),當異步任務從任務隊列回到執(zhí)行棧,回調(diào)函數(shù)就會執(zhí)行。事件循環(huán)主線程從任務隊列中讀取事件,這個過程是循環(huán)不斷的,所以整個的這種運行機制又稱為。事件循環(huán)事件循環(huán)是指主線程重復從消息隊列中取消息執(zhí)行的過程。 參考鏈接:這一次,徹底弄懂 JavaScript 執(zhí)行機制https://zhuanlan.zhihu.com/p/...從瀏覽器多進程到JS單線程,JS運行機制...
摘要:有兩種事件處理程序的方式。第一種第二種事件當調(diào)整瀏覽器的窗口到一個新的寬度或高度時,就會觸發(fā)事件。事件在元素獲得焦點時觸發(fā)。這個事件冒泡某些瀏覽器不支持。事件在鼠標光標從元素外部首次移動到元素范圍內(nèi)時觸發(fā)。事件這個事件跟蹤鼠標滾輪。 JavaScript簡單入門可以看看我丑丑的Github博客JavaScript簡單入門 本文主要簡單介紹以下幾類事件: UI事件 焦點事件 鼠標與滾輪...
摘要:響應某個事件的函數(shù)就叫事件處理程序或事件偵聽器。為事件指定事件處理程序的方法主要有種。事件處理程序事件直接加在元素上。事件委托利用冒泡的原理,把事件加到父元素或祖先元素上,觸發(fā)執(zhí)行效果,解決事件處理程序過多問題。事件委托優(yōu)點提高性能。 JavaScript簡單入門可以看看我丑丑的Github博客JavaScript簡單入門 事件 JavaScript與HTML之間的交互是通過事件實現(xiàn)的...
摘要:提示如需移除事件處理程序,請使用方法。說明和綁定的點擊事件被的事件覆蓋。分析不同的綁定方式執(zhí)行順序屬性元素事件事件。元素綁定事件刪除按鈕。屬性綁定事件動態(tài)綁定事件方法的方法的屬性綁定。 一、動態(tài)監(jiān)聽加載對象 當使用js或jQuery動態(tài)創(chuàng)建元素(例如append,appendChildren),再用on(事件, function(){...})或addEventListener監(jiān)聽事件...
摘要:鼠標滾輪事件當在被綁定的對象上如某個或者發(fā)生鼠標滾輪滾動時觸發(fā)。 鼠標滾輪事件 當在被綁定的對象上(如:某個div或者doucument)發(fā)生鼠標滾輪滾動時觸發(fā)。 在不同的瀏覽器中有不同的表現(xiàn)形式: 一、ie/chrome下的事件 : onmousewheel 事件綁定方式:on 或者 addEventListener[attachEvent] 獲取滾輪事件具體信息:ev...
摘要:要想注冊過的事件能夠被解除,必須將回調(diào)函數(shù)保存起來,否則無法解除。當用阻止瀏覽器的默認行為時,會做下面這件事停止回調(diào)函數(shù)執(zhí)行并立即返回。 showImg(https://segmentfault.com/img/bVboOcb?w=750&h=422); 前言 這是前端面試題系列的第 7 篇,你可能錯過了前面的篇章,可以在這里找到: 理解函數(shù)的柯里化 ES6 中箭頭函數(shù)的用法 thi...
閱讀 2337·2019-08-30 15:44
閱讀 1260·2019-08-30 13:01
閱讀 3307·2019-08-30 11:22
閱讀 3093·2019-08-29 15:23
閱讀 1614·2019-08-29 12:22
閱讀 3366·2019-08-26 13:58
閱讀 3439·2019-08-26 12:17
閱讀 3479·2019-08-26 12:16