成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

DOM事件機(jī)制

laznrbfe / 3171人閱讀

摘要:而事件分為個(gè)級(jí)別級(jí)事件處理,級(jí)事件處理和級(jí)事件處理。一個(gè)事件發(fā)生后,會(huì)在子元素和父元素之間傳播。也就是說(shuō),始終是監(jiān)聽(tīng)事件者,而是事件的真正發(fā)出者。五參考文章級(jí)別與事件事件機(jī)制解惑事件模型事件委托詳解事件的學(xué)與記和和的區(qū)別

前言

本文主要介紹DOM事件級(jí)別、DOM事件模型、事件流、事件代理和Event對(duì)象常見(jiàn)的應(yīng)用,希望對(duì)你們有些幫助和啟發(fā)!

本文首發(fā)地址為GitHub博客,寫(xiě)文章不易,請(qǐng)多多支持與關(guān)注!

一、DOM事件級(jí)別

DOM級(jí)別一共可以分為四個(gè)級(jí)別:DOM0級(jí)、DOM1級(jí)、DOM2級(jí)和DOM3級(jí)。而DOM事件分為3個(gè)級(jí)別:DOM 0級(jí)事件處理,DOM 2級(jí)事件處理和DOM 3級(jí)事件處理。由于DOM 1級(jí)中沒(méi)有事件的相關(guān)內(nèi)容,所以沒(méi)有DOM 1級(jí)事件。

1.DOM 0級(jí)事件

el.onclick=function(){}

// 例1
var btn = document.getElementById("btn");
 btn.onclick = function(){
     alert(this.innerHTML);
 }

當(dāng)希望為同一個(gè)元素/標(biāo)簽綁定多個(gè)同類(lèi)型事件的時(shí)候(如給上面的這個(gè)btn元素綁定3個(gè)點(diǎn)擊事件),是不被允許的。DOM0事件綁定,給元素的事件行為綁定方法,這些方法都是在當(dāng)前元素事件行為的冒泡階段(或者目標(biāo)階段)執(zhí)行的。

2.DOM 2級(jí)事件

el.addEventListener(event-name, callback, useCapture)

event-name: 事件名稱(chēng),可以是標(biāo)準(zhǔn)的DOM事件

callback: 回調(diào)函數(shù),當(dāng)事件觸發(fā)時(shí),函數(shù)會(huì)被注入一個(gè)參數(shù)為當(dāng)前的事件對(duì)象 event

useCapture: 默認(rèn)是false,代表事件句柄在冒泡階段執(zhí)行

// 例2
var btn = document.getElementById("btn");
btn.addEventListener("click", test, false);
function test(e){
    e = e || window.event;
    alert((e.target || e.srcElement).innerHTML);
    btn.removeEventListener("click", test)
}
//IE9-:attachEvent()與detachEvent()。
//IE9+/chrom/FF:addEventListener()和removeEventListener()

IE9以下的IE瀏覽器不支持 addEventListener()和removeEventListener(),使用 attachEvent()與detachEvent() 代替,因?yàn)镮E9以下是不支持事件捕獲的,所以也沒(méi)有第三個(gè)參數(shù),第一個(gè)事件名稱(chēng)前要加on。

3.DOM 3級(jí)事件

在DOM 2級(jí)事件的基礎(chǔ)上添加了更多的事件類(lèi)型。

UI事件,當(dāng)用戶(hù)與頁(yè)面上的元素交互時(shí)觸發(fā),如:load、scroll

焦點(diǎn)事件,當(dāng)元素獲得或失去焦點(diǎn)時(shí)觸發(fā),如:blur、focus

鼠標(biāo)事件,當(dāng)用戶(hù)通過(guò)鼠標(biāo)在頁(yè)面執(zhí)行操作時(shí)觸發(fā)如:dblclick、mouseup

滾輪事件,當(dāng)使用鼠標(biāo)滾輪或類(lèi)似設(shè)備時(shí)觸發(fā),如:mousewheel

文本事件,當(dāng)在文檔中輸入文本時(shí)觸發(fā),如:textInput

鍵盤(pán)事件,當(dāng)用戶(hù)通過(guò)鍵盤(pán)在頁(yè)面上執(zhí)行操作時(shí)觸發(fā),如:keydown、keypress

合成事件,當(dāng)為IME(輸入法編輯器)輸入字符時(shí)觸發(fā),如:compositionstart

變動(dòng)事件,當(dāng)?shù)讓覦OM結(jié)構(gòu)發(fā)生變化時(shí)觸發(fā),如:DOMsubtreeModified

同時(shí)DOM3級(jí)事件也允許使用者自定義一些事件。

二、DOM事件模型和事件流

DOM事件模型分為捕獲和冒泡。一個(gè)事件發(fā)生后,會(huì)在子元素和父元素之間傳播(propagation)。這種傳播分成三個(gè)階段。

(1)捕獲階段:事件從window對(duì)象自上而下向目標(biāo)節(jié)點(diǎn)傳播的階段;

(2)目標(biāo)階段:真正的目標(biāo)節(jié)點(diǎn)正在處理事件的階段;

(3)冒泡階段:事件從目標(biāo)節(jié)點(diǎn)自下而上向window對(duì)象傳播的階段。

DOM事件捕獲的具體流程

捕獲是從上到下,事件先從window對(duì)象,然后再到document(對(duì)象),然后是html標(biāo)簽(通過(guò)document.documentElement獲取html標(biāo)簽),然后是body標(biāo)簽(通過(guò)document.body獲取body標(biāo)簽),然后按照普通的html結(jié)構(gòu)一層一層往下傳,最后到達(dá)目標(biāo)元素。

而事件冒泡的流程剛好是事件捕獲的逆過(guò)程。
接下來(lái)我們看個(gè)事件冒泡的例子:

// 例3
...... window.onclick = function() { console.log("window"); }; document.onclick = function() { console.log("document"); }; document.documentElement.onclick = function() { console.log("html"); }; document.body.onclick = function() { console.log("body"); } outer.onclick = function(ev) { console.log("outer"); }; inner.onclick = function(ev) { console.log("inner"); };

正如我們上面提到的onclick給元素的事件行為綁定方法都是在當(dāng)前元素事件行為的冒泡階段(或者目標(biāo)階段)執(zhí)行的。

三、事件代理(事件委托)

由于事件會(huì)在冒泡階段向上傳播到父節(jié)點(diǎn),因此可以把子節(jié)點(diǎn)的監(jiān)聽(tīng)函數(shù)定義在父節(jié)點(diǎn)上,由父節(jié)點(diǎn)的監(jiān)聽(tīng)函數(shù)統(tǒng)一處理多個(gè)子元素的事件。這種方法叫做事件的代理(delegation)。

1.優(yōu)點(diǎn)

減少內(nèi)存消耗,提高性能

假設(shè)有一個(gè)列表,列表之中有大量的列表項(xiàng),我們需要在點(diǎn)擊每個(gè)列表項(xiàng)的時(shí)候響應(yīng)一個(gè)事件

// 例4
  • item 1
  • item 2
  • item 3
  • ......
  • item n

如果給每個(gè)列表項(xiàng)一一都綁定一個(gè)函數(shù),那對(duì)于內(nèi)存消耗是非常大的,效率上需要消耗很多性能。借助事件代理,我們只需要給父容器ul綁定方法即可,這樣不管點(diǎn)擊的是哪一個(gè)后代元素,都會(huì)根據(jù)冒泡傳播的傳遞機(jī)制,把容器的click行為觸發(fā),然后把對(duì)應(yīng)的方法執(zhí)行,根據(jù)事件源,我們可以知道點(diǎn)擊的是誰(shuí),從而完成不同的事。

動(dòng)態(tài)綁定事件

在很多時(shí)候,我們需要通過(guò)用戶(hù)操作動(dòng)態(tài)的增刪列表項(xiàng)元素,如果一開(kāi)始給每個(gè)子元素綁定事件,那么在列表發(fā)生變化時(shí),就需要重新給新增的元素綁定事件,給即將刪去的元素解綁事件,如果用事件代理就會(huì)省去很多這樣麻煩。

2.如何實(shí)現(xiàn)

接下來(lái)我們來(lái)實(shí)現(xiàn)上例中父層元素 #list 下的 li 元素的事件委托到它的父層元素上:

// 給父層元素綁定事件
document.getElementById("list").addEventListener("click", function (e) {
  // 兼容性處理
  var event = e || window.event;
  var target = event.target || event.srcElement;
  // 判斷是否匹配目標(biāo)元素
  if (target.nodeName.toLocaleLowerCase === "li") {
    console.log("the content is: ", target.innerHTML);
  }
});
四、Event對(duì)象常見(jiàn)的應(yīng)用

event. preventDefault()

如果調(diào)用這個(gè)方法,默認(rèn)事件行為將不再觸發(fā)。什么是默認(rèn)事件呢?例如表單一點(diǎn)擊提交按鈕(submit)跳轉(zhuǎn)頁(yè)面、a標(biāo)簽?zāi)J(rèn)頁(yè)面跳轉(zhuǎn)或是錨點(diǎn)定位等。

很多時(shí)候我們使用a標(biāo)簽僅僅是想當(dāng)做一個(gè)普通的按鈕,點(diǎn)擊實(shí)現(xiàn)一個(gè)功能,不想頁(yè)面跳轉(zhuǎn),也不想錨點(diǎn)定位。

//方法一:
鏈接

也可以通過(guò)JS方法來(lái)阻止,給其click事件綁定方法,當(dāng)我們點(diǎn)擊A標(biāo)簽的時(shí)候,先觸發(fā)click事件,其次才會(huì)執(zhí)行自己的默認(rèn)行為

//方法二:
鏈接
//方法三:
鏈接

接下來(lái)我們看個(gè)例子:輸入框最多只能輸入六個(gè)字符,如何實(shí)現(xiàn)?

// 例5
 
 

event.stopPropagation() & event.stopImmediatePropagation()

event.stopPropagation() 方法阻止事件冒泡到父元素,阻止任何父事件處理程序被執(zhí)行。上面提到事件冒泡階段是指事件從目標(biāo)節(jié)點(diǎn)自下而上向window對(duì)象傳播的階段。
我們?cè)诶?的inner元素click事件上,添加event.stopPropagation()這句話(huà)后,就阻止了父事件的執(zhí)行,最后只打印了"inner"。

 inner.onclick = function(ev) {
    console.log("inner");
    ev.stopPropagation();
};

stopImmediatePropagation 既能阻止事件向父元素冒泡,也能阻止元素同事件類(lèi)型的其它監(jiān)聽(tīng)器被觸發(fā)。而 stopPropagation 只能實(shí)現(xiàn)前者的效果。我們來(lái)看個(gè)例子:


  

......
const btn = document.querySelector("#btn");
btn.addEventListener("click", event => {
  console.log("btn click 1");
  event.stopImmediatePropagation();
});
btn.addEventListener("click", event => {
  console.log("btn click 2");
});
document.body.addEventListener("click", () => {
  console.log("body click");
});
// btn click 1

如上所示,使用 stopImmediatePropagation后,點(diǎn)擊按鈕時(shí),不僅body綁定事件不會(huì)觸發(fā),與此同時(shí)按鈕的另一個(gè)點(diǎn)擊事件也不觸發(fā)。

event.target & event.currentTarget

老實(shí)說(shuō)這兩者的區(qū)別,并不好用文字描述,我們先來(lái)看個(gè)例子:

當(dāng)我們點(diǎn)擊最里層的元素d的時(shí)候,會(huì)依次輸出:

target:d¤tTarget:d
target:d¤tTarget:c
target:d¤tTarget:b
target:d¤tTarget:a

從輸出中我們可以看到,event.target指向引起觸發(fā)事件的元素,而event.currentTarget則是事件綁定的元素,只有被點(diǎn)擊的那個(gè)目標(biāo)元素的event.target才會(huì)等于event.currentTarget也就是說(shuō),event.currentTarget始終是監(jiān)聽(tīng)事件者,而event.target是事件的真正發(fā)出者

五、參考文章

DOM級(jí)別與DOM事件

DOM事件機(jī)制解惑

事件模型

JavaScript 事件委托詳解

JavaScript 事件的學(xué)與記:stopPropagation 和 stopImmediatePropagation

event.target和event.currentTarget的區(qū)別

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/99732.html

相關(guān)文章

  • JavaScript中幾個(gè)重要的知識(shí)點(diǎn)(2) ---- DOM事件

    摘要:使用來(lái)移除事件,參數(shù)必須與要移除的事件處理函數(shù)地址指針相同。在低版本瀏覽器中,綁定級(jí)事件的方法為中的級(jí)事件的事件處理程序都是在冒泡階段執(zhí)行的。 JavaScript中幾個(gè)最重要的大知識(shí)點(diǎn) 面向?qū)ο?DOM事件 異步交互ajax 事件 事件就是文檔和瀏覽器的瞬間交互行為 1.事件類(lèi)型 點(diǎn)擊: click 滾輪: scroll 滑動(dòng): move 進(jìn)入: enter 加載: load ...

    dantezhao 評(píng)論0 收藏0
  • 談?wù)凴eact事件機(jī)制和未來(lái)(react-events)

    摘要:另外第三方也可以通過(guò)的事件插件機(jī)制來(lái)合成自定義事件,盡管很少人這么做。抽象跨平臺(tái)事件機(jī)制。打算干預(yù)事件的分發(fā)。事件是的一個(gè)自定義事件,旨在規(guī)范化表單元素的變動(dòng)事件。 showImg(https://segmentfault.com/img/remote/1460000019961124?w=713&h=307); 當(dāng)我們?cè)诮M件上設(shè)置事件處理器時(shí),React并不會(huì)在該DOM元素上直接綁定...

    TNFE 評(píng)論0 收藏0
  • DOM事件機(jī)制

    摘要:而事件分為個(gè)級(jí)別級(jí)事件處理,級(jí)事件處理和級(jí)事件處理。一個(gè)事件發(fā)生后,會(huì)在子元素和父元素之間傳播。也就是說(shuō),始終是監(jiān)聽(tīng)事件者,而是事件的真正發(fā)出者。五參考文章級(jí)別與事件事件機(jī)制解惑事件模型事件委托詳解事件的學(xué)與記和和的區(qū)別 前言 本文主要介紹DOM事件級(jí)別、DOM事件模型、事件流、事件代理和Event對(duì)象常見(jiàn)的應(yīng)用,希望對(duì)你們有些幫助和啟發(fā)! 本文首發(fā)地址為GitHub博客,寫(xiě)文章不易,...

    cooxer 評(píng)論0 收藏0
  • react的事件機(jī)制

    摘要:本博客大概介紹一下的事件機(jī)制,并給出整體的設(shè)計(jì)圖,但不涉及底層的源碼結(jié)構(gòu)分析。整個(gè)設(shè)計(jì)圖以上是對(duì)的合成事件一個(gè)大概的介紹,里面還有很多細(xì)節(jié)和原理沒(méi)說(shuō)到,有興趣的同學(xué)可以進(jìn)一步研究一下源碼的細(xì)節(jié)。 好久沒(méi)寫(xiě)博客了,前段時(shí)間太忙以至于平時(shí)的積累都記錄在內(nèi)網(wǎng)的wiki里,趁著這幾天有空,將這段時(shí)間所積累的干貨慢慢的分享出來(lái),如果內(nèi)容有不正確的地方,歡迎糾正。 本博客大概介紹一下react的事...

    bladefury 評(píng)論0 收藏0
  • 深入理解js Dom事件機(jī)制(二)——添加事件處理程序

    摘要:深入理解事件機(jī)制一事件流事件就是當(dāng)用戶(hù)或者瀏覽器自身執(zhí)行的某種動(dòng)作,諸如等都是事件的名稱(chēng),那響應(yīng)個(gè)事件的函數(shù)就稱(chēng)為事件處理程序事件處理函數(shù)事件句柄。 深入理解js Dom事件機(jī)制(一)——事件流 事件就是當(dāng)用戶(hù)或者瀏覽器自身執(zhí)行的某種動(dòng)作,諸如 click、mouseover等都是事件的名稱(chēng),那響應(yīng)個(gè)事件的函數(shù)就稱(chēng)為事件處理程序(事件處理函數(shù)、事件句柄)。 事件處理程序的名字都是以on...

    ddongjian0000 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<