摘要:事件處理程序事件偵聽器的設定級級首先講級事件處理程序對事件的方式被稱為事件處理程序或事件偵聽器,但這兩者之間是有區別的。此外,不能對事件目標事件類型執行階段都相同的對象注冊多個相同的事件偵聽器。
關于這一篇章有太多對于我來說雜且亂的知識點,單單是分別DOM層級劃分我看過的文章就有(0,2,3)的,(0,2)的,由于自己知識掌握還很薄弱所以只能參考別人文章結合自己理解來寫,這其中也涉及到一點W3C標準制定史的發展,不了解的像我這樣的小白肯定會一頭霧水啦。
主要的有,DOM層級事件處理、事件流、熟練一些事件處理方法等 簡介JavaScript中,最重要的就是對事件進行處理。Web應用也是通過事件驅動程序設計其功能的。在事件驅動程序設計中,需要注冊不同事件的處理方式。
在注冊了事件的處理方式后,瀏覽器就會在該事件發生時執行所注冊的處理方式。所注冊的處理方式被稱作事件處理程序、事件句柄或事件監聽器。
JavaScript程序設計的基本內容之一就是獲取需要對事件進行捕捉的元素,并針對該元素注入相應的事件處理程序。
對事件的方式被稱為事件處理程序或事件偵聽器,但這兩者之間是有區別的。
設定方法不同
支持處理元素數量不同
詳細點,說一些對事件處理進行設定的方式
指定為HTML元素的屬性(DOM 0級)
指定為DOM 元素的屬性(DOM 0級)
通過EventTarget.addEventListener進行設定(DOM 2級)
1. 首先是第一個,指定為HTML元素的屬性這個例子中,通過字符串對onclick事件處理程序將要執行的JavaScript代碼進行了設定。如果包含代碼,可以分號分隔,當然,事件另外定義一個函數之后再執行該函數的方式也不會有問題。
優點:設定步驟簡單,確保事件處理程序會在載入時被設定。如果使用第二種方式(DOM元素屬性),元素被載入時,其事件處理程序可能還沒有注冊,這時用戶執行任何本應觸發事件的操作,也沒有效果。
注意:這里的onclick全都是以小寫字母書寫。HTML不會區分大小寫字母,所以改寫為onClick也沒有問題。但是XHTML會區分大小寫字母,所以最好還是使用全部小寫的onclick,提高兼容性。小應用:如果事件處理程序返回一個false值,則會取消該事件的默認行為,(啥是默認行為,比如點擊a標簽會跳轉鏈接,表單的提交等這些就屬于默認行為),例如:當onsubmit事件處理程序返回一個false,表單內容不會被發送,,這可以發現內容有誤時返回false取消表單數據發送。或者像下面代碼,取消頁面跳轉。
BAIDU.com例:
我們在DIV上設置CSS樣式方便我們查看,此時目標元素就是DIV。隨著事件流入.....到目標元素,發現我們的button雖然設置了事件偵聽器,卻沒有執行。因為此時button已經不是目標元素,事件流經過時,它是處于流入階段也就是捕獲階段的,但button是冒泡階段調用,所以不會執行button,“忽略了它”。之后便是老套路:DIV-BODY-DOCUMENT.
接下來我們看看捕獲階段:
var div = document.getElementById("div"); var btn = document.getElementById("btn"); // 由內之外 btn.addEventListener("click",function(e){ alert("Now to the element BUTTON"); },true); div.addEventListener("click",function(e){ alert("Now to the element DIV"); },true); document.body.addEventListener("click",function(e){ alert("Now to the element BODY"); },true); document.documentElement.addEventListener("click",function(e){ alert("Now to the element DOCUMENT"); },true); // click me! DOCUMENT-BODY-DIV-BUTTON點擊click,事件流流入,事件目標是button,則到button之前是捕獲階段,恰好這些元素剛好是在捕獲階段設定事件偵聽器,則按照DOM數規則,由外至內一層一層執行。但是注意:事件目標button是在目標階段執行的,不是捕獲也不是冒泡,不信?我們用eventPhase來測試:
btn.addEventListener("click",function(e){ alert("Now to the element BUTTON"); alert(e.eventPhase); },false); // 不論是true還是false,只要點擊的是button元素,eventPhase都是返回2找到規律了嗎?也沒有什么規律,腦子里能模擬出DOM樹就都清楚了。
btn.addEventListener("click",function(e){ alert("Now to the element BUTTON"); },false); div.addEventListener("click",function(e){ alert("Now to the element DIV"); alert(e.eventPhase); },true); document.body.addEventListener("click",function(e){ alert("Now to the element BODY"); },false); document.documentElement.addEventListener("click",function(e){ alert("Now to the element DOCUMENT"); },true); // click me! DOCUMENT-DIV(2)-BODY目標節點是DIV,那事件流流入最深處就是DIV,DIV就是事件目標,則button根本不會執行,不管它是捕獲還是冒泡,因為它處于DOM樹最深處。
如何取消事件流傳播? 1.Event.stopPropagation()終止事件在傳播過程的捕獲、目標處理或起泡階段進一步傳播。調用該方法后,該節點上處理該事件的處理程序將被調用,事件不再被分派到其他節點。
該方法將停止事件的傳播,阻止它被分派到其他 Document 節點。在事件傳播的任何階段都可以調用它。注意,雖然該方法不能阻止同一個 Document 節點上的其他事件句柄被調用,但是它可以阻止把事件分派到其他節點。
btn.addEventListener("click",function(e){ alert("Now to the element BUTTON"); e.stopPropagation(); },false); div.addEventListener("click",function(e){ alert("Now to the element DIV"); },false); document.body.addEventListener("click",function(e){ alert("Now to the element BODY"); },false); document.documentElement.addEventListener("click",function(e){ alert("Now to the element DOCUMENT"); },false); // click me! BUTTON此時只會在button執行一次事件偵聽器,之后的傳播被阻止了。
但是如果你點擊的是DIV,那依然會往上一層一層執行事件偵聽器,設置stopPropagation()的是button。
2. event.stopImmediatePropagation()
以此類推...如果你希望阻止當前節點上的其他回調函數被調用的話,你可以使用更激進的event.stopImmediatePropagation()方法。
MDN:如果某個元素有多個相同類型事件的事件監聽函數,則當該類型的事件觸發時,多個事件監聽函數將按照順序依次執行.如果某個監聽函數執行了 event.stopImmediatePropagation()方法,則除了該事件的冒泡行為被阻止之外(event.stopPropagation方法的作用),該元素綁定的后序相同類型事件的監聽函數的執行也將被阻止。
看MDN這段話我再試著理解理解,一直再說這事件傳播,傳播,到底是只有跨節點的事件處理程序被觸發才能叫傳播,同節點上,多個時間偵聽器這個不能算是傳播,這樣理解就好了。
btn.addEventListener("click",function(e){ alert("1"); },false); btn.addEventListener("click",function(e){ alert("2"); e.stopPropagation(); // e.stopImmediatePropagation() alert("2-1"); },false); btn.addEventListener("click",function(e){ alert("3"); },false); div.addEventListener("click",function(e){ alert("div"); },false)對于e.stopPropagation()而言,它能阻止的是所有階段的事件偵聽器傳播,結果就是調用該方法的節點上所有的時間偵聽器可以觸發,但是傳播被終止,也就是DIV沒有了。彈出1-2-(2-3)-3,這些都是btn節點上的。
換到e.stopImmediatePropagation() ,那它就是精確到節點內的事件偵聽器了
document.documentElement.addEventListener("click",function(e){ alert("document") },true) btn.addEventListener("click",function(e){ alert("1"); },false); btn.addEventListener("click",function(e){ alert("2"); e.stopImmediatePropagation(); // 這里往后的節點內事件偵聽器不能執行 // e.stopPropagation(); alert("2-1"); },false); btn.addEventListener("click",function(e){ alert("3"); },false); div.addEventListener("click",function(e){ alert("div"); },false) // document/1/2/2-1 // 阻止事件流中當前節點的和所有后續節點的事件監聽器的執行。即影響當前結點的事件監聽器這就是MDN:該元素綁定的后序相同類型事件的監聽函數的執行也將被阻止,這句話的意思了。
默認操作Event.preventDefault()在默認情況下,點擊a描點元素后,將會跳轉至鏈接頁面。而如果在這時執行了Event.preventDefault()方法,則不會發生這一行為。這個方法作用等同于讓一個指定為了HTML標簽屬性或DOM屬性的事件處理程序返回一個false值。
segmentfault不過也有一些事件無法通過使用preventDefault()方法來中止。blur事件就是其中之一,它是一個焦點移動至其他元素時被觸發的事件。
IE
stopPropagation()和preventDefault()方法不僅能夠用于事件冒泡階段,在其他階段中也能夠使用這些方法。IE瀏覽器下,綁定/刪除(attachEvent/detachEvent)、阻止事件冒泡(cancelBubble)、阻止事件的默認行為(returnValue)、用于獲取事件的目標(srcElement)等等需要另外探討,大體相同。到時候我另開一篇來繼續學習。
Event接口對象 關于target和currentTarget這兩個屬性在不同情況下指向也不盡相同,先來看看概念
target:事件屬性可返回事件的目標節點(觸發該事件的節點),如生成事件的元素、文檔或窗口。
currentTarget 事件屬性返回其監聽器觸發事件的節點,即當前處理該事件的元素、文檔或窗口。
event.currentTarget指向事件所綁定的元素,而event.target始終指向事件發生的元素。
在捕獲和起泡階段,該屬性是非常有用的,因為在這兩個節點,它不同于 target 屬性。
不管你在哪個節點注冊事件偵聽器,引發這一系列程序的"罪魁禍首"是button,所以target指向它。如果button節點換成a描點元素,你再點擊a,target就指向a(理解為事件目標也行)
而currentTarget指向的是這個事件流三個階段中,事件偵聽器綁定的元素。由于我只是初步了解了一下,重點在應用,沒有幾個實實在在的前端練習是不行的。
目前我只是簡單了解而已,靈活運用這些方法需要不斷的敲敲敲,練項目造輪子。這里引幾個文章吧DOM事件簡介
stopImmediatePropagation應用
事件綁定的幾種方式、stopImmediatePropagation和stopPropagation的區別
Javascript DOM Event對象方法詳解 - 博客頻道 - CSDN.NET
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/83154.html
摘要:好啦我們已經解決了是啥的疑問了,現在回去開始一步步解讀如何實現手動觸發事件。我們主要看看這里面幾乎含有如何手動觸發一個事件的大部分步驟和內容。 前言 前端在最近幾年實在火爆異常,vue、react、angular各路框架層出不窮,咱們要是不知道個雙向數據綁定,不曉得啥是虛擬DOM,也許就被鄙視了。火熱的背后往往也是無盡的浮躁,學習這些先進流行的類庫或者框架可以讓我們走的更快,但是靜下心...
摘要:好啦我們已經解決了是啥的疑問了,現在回去開始一步步解讀如何實現手動觸發事件。我們主要看看這里面幾乎含有如何手動觸發一個事件的大部分步驟和內容。 前言 前端在最近幾年實在火爆異常,vue、react、angular各路框架層出不窮,咱們要是不知道個雙向數據綁定,不曉得啥是虛擬DOM,也許就被鄙視了。火熱的背后往往也是無盡的浮躁,學習這些先進流行的類庫或者框架可以讓我們走的更快,但是靜下心...
摘要:好啦我們已經解決了是啥的疑問了,現在回去開始一步步解讀如何實現手動觸發事件。我們主要看看這里面幾乎含有如何手動觸發一個事件的大部分步驟和內容。 前言 前端在最近幾年實在火爆異常,vue、react、angular各路框架層出不窮,咱們要是不知道個雙向數據綁定,不曉得啥是虛擬DOM,也許就被鄙視了。火熱的背后往往也是無盡的浮躁,學習這些先進流行的類庫或者框架可以讓我們走的更快,但是靜下心...
摘要:但是通過添加的匿名函數無法移除,最好是在其他地方定義事件處理程序的函數,然后將該函數的名稱傳給第二個參數。一中的事件對象對象兼容級和級的瀏覽器將對象傳入到事件處理程序中。 一、事件流 假設有如下HTML代碼: Event Click me 其DOM樹如下圖所示:showImg(https://segmentfault.com/img/bVUUWA?w=50...
摘要:外觀模式在中常常用于解決瀏覽器兼容性問題。實現外觀模式不僅簡化類中的接口,而且對接口與調用者也進行了解耦。外觀模式的優勢是易于使用,而且本身也比較輕量級。 1. 簡介 外觀模式(Facade)為子系統中的一組接口提供了一個一致的界面,此模塊定義了一個高層接口,這個接口值得這一子系統更加容易使用。外觀模式在JS中常常用于解決瀏覽器兼容性問題。 2. 實現 外觀模式不僅簡化類中的接口,而且...
閱讀 1245·2023-04-25 18:57
閱讀 2127·2023-04-25 16:28
閱讀 3927·2021-11-24 09:39
閱讀 3631·2021-11-16 11:45
閱讀 1817·2021-10-13 09:40
閱讀 1260·2019-08-30 15:52
閱讀 1716·2019-08-30 10:57
閱讀 657·2019-08-29 16:55