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