DOM 事件模型

什么是 DOM 事件

  • DOM 事件是瀏覽器的一個(gè)功能,是瀏覽器或者用戶針對(duì)頁面做出的某些動(dòng)作匣椰,比如點(diǎn)擊板惑,鼠標(biāo)移動(dòng)橄镜,鍵盤輸入等。
  • DOM 事件是用戶與頁面進(jìn)行交互的核心冯乘,當(dāng)事件觸發(fā)時(shí)洽胶,可以綁定一個(gè)或多個(gè)事件處理函數(shù),來完成我們要實(shí)現(xiàn)的功能裆馒。

DOM 事件模型

DOM 事件模型分類兩種姊氓,事件冒泡和事件捕獲。當(dāng)某一事件觸發(fā)時(shí)喷好,先執(zhí)行捕獲再執(zhí)行冒泡翔横。

事件冒泡

當(dāng)子元素的事件類型觸發(fā)時(shí),所有父元素上綁定同類型事件均會(huì)從內(nèi)到外層層觸發(fā)梗搅。

代碼示例

<body>
    <div class="grandparent">
        祖父元素
        <div class="parent">
            父元素
            <div class="children">子元素</div>
        </div>
    </div>
    <script>
        let children = document.querySelector('.children')
        let parent = document.querySelector('.parent')
        let grandparent = document.querySelector('.grandparent')
       
        // 這里的綁定的三個(gè)事件類型相同禾唁,均為 click,如果不相同則不會(huì)執(zhí)行事件冒泡
       children.addEventListener('click', () => {
            console.log ('子元素被點(diǎn)擊了')
        })

        parent.addEventListener('click', () => {
            console.log ('父元素被點(diǎn)擊了')
        })

        grandparent.addEventListener('click', () => {
            console.log ('祖父元素被點(diǎn)擊了')
        })
    </script>
</body>

當(dāng)點(diǎn)擊子元素時(shí)无切,控制臺(tái)打印如下結(jié)果


事件捕獲

當(dāng)子元素的事件類型觸發(fā)時(shí)荡短,所有父元素上綁定的同類型事件均會(huì)從外到內(nèi)層層觸發(fā)。

代碼示例

<body>

    <div class="grandparent">
        祖父元素
        <div class="parent">
            父元素
            <div class="children">子元素</div>
        </div>
    </div>
    <script>
        let children = document.querySelector('.children')
        let parent = document.querySelector('.parent')
        let grandparent = document.querySelector('.grandparent')
    
        children.addEventListener('click', () => {
            console.log ('子元素被點(diǎn)擊了')
        }, true)

        parent.addEventListener('click', () => {
            console.log ('父元素被點(diǎn)擊了')
        }, true)

        grandparent.addEventListener('click', () => {
            console.log ('祖父元素被點(diǎn)擊了')
        }, true)
    </script>
</body> 

當(dāng)點(diǎn)擊子元素時(shí)哆键,控制臺(tái)打印如下結(jié)果


事件對(duì)象

每當(dāng)事件觸發(fā)時(shí)掘托,瀏覽器會(huì)把當(dāng)前事件觸發(fā)的詳情信息記錄下來,并把它們封裝成一個(gè)對(duì)象籍嘹,可以傳遞給事件處理函數(shù)闪盔。

 children.addEventListener('click', (e) => {
            console.log ('子元素被點(diǎn)擊了')
            console.log(e)
        }, true) // e 為事件對(duì)象

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

e.target 用戶操作的元素
e.currentTarget 程序員監(jiān)聽的元素

代碼示例

 children.addEventListener('click', (e) => {
            console.log('子元素被點(diǎn)擊了')
            console.log(e.target)    // 輸出子元素
            console.log(e.currentTarget);  // 輸出子元素
        })

parent.addEventListener('click', (e) => {
            console.log('父元素被點(diǎn)擊了')
            console.log(e.target)    // 輸出子元素或父元素
            console.log(e.currentTarget)  // 輸出父元素
        })
console.log(e)  // 報(bào)錯(cuò) Uncaught ReferenceError: e is not defined

當(dāng)點(diǎn)擊子元素時(shí),控制臺(tái)打印出如下結(jié)果


兩個(gè)點(diǎn)擊事件的 e.target 值都是用戶點(diǎn)擊子元素噩峦,而 e.currentTarget 則是事件觸發(fā)的元素锭沟,用戶點(diǎn)擊觸發(fā)的元素 e.targete.currentTarget 的值是相同的,通過事件冒泡和事件捕獲觸發(fā)的元素识补,e.targete.currentTarget 的值是不相同的族淮。

當(dāng)事件結(jié)束后,事件對(duì)象 e 就不存在凭涂。

阻止事件冒泡和事件捕獲

通過 e.stopPropagation() 可以阻止事件冒泡和事件捕獲

阻止事件冒泡
代碼示例

 children.addEventListener('click', (e) => {
            console.log('子元素被點(diǎn)擊了')
        })

parent.addEventListener('click', (e) => {
            console.log('父元素被點(diǎn)擊了')
            e.stopPropagation()   // 當(dāng)代碼執(zhí)行到這里時(shí)祝辣,停止事件傳播
        })

grandparent.addEventListener('click', (e) => {
            console.log('祖父元素被點(diǎn)擊了')    //  這里不會(huì)打印出來
        })

阻止事件捕獲

  • 子元素不能阻止父元素的事件捕獲
    代碼示例
 children.addEventListener('click', (e) => {
            console.log('子元素被點(diǎn)擊了')  //  這里不會(huì)打印出來
        })

parent.addEventListener('click', (e) => {
            console.log('父元素被點(diǎn)擊了')
            e.stopPropagation()   // 當(dāng)代碼執(zhí)行到這里時(shí),停止事件傳播
        })

grandparent.addEventListener('click', (e) => {
            console.log('祖父元素被點(diǎn)擊了')    
        })

取消默認(rèn)事件

e.preventDefault()   // w3c 的寫法
e.returnValue = false   // IE 的寫法
  • 元素有默認(rèn)事件才可以取消切油,如果元素本身沒有默認(rèn)事件或者元素不支持取消默認(rèn)事件(如滾動(dòng)條)蝙斜,則調(diào)用無效。
  • 不可取消冒泡和不可取消默認(rèn)事件的元素可以通過 MDN 英文版搜索 元素 event 澎胡,看到 Bubbles (冒泡) 和(Cancelable)是否支持孕荠。

什么元素有默認(rèn)事件

<a> 鏈接
<inpunt type='submit'> 表單提交按鈕
οncοntextmenu 右鍵菜單
onmousewheel 鼠標(biāo)滾輪
touchstart 觸屏滑動(dòng)

代碼示例

<body>
<a >百度</a>
    <script>
        a.onclick = (e) => {
            if (e.preventDefault) {
                e.preventDefault()
                console.log('鏈接跳轉(zhuǎn)被阻止了')
            } else {
                window.event.returnValue = false
                console.log('鏈接跳轉(zhuǎn)被阻止了')
            }
        }
    </script>
</body>
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末娩鹉,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子稚伍,更是在濱河造成了極大的恐慌弯予,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,496評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件个曙,死亡現(xiàn)場(chǎng)離奇詭異锈嫩,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)垦搬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門呼寸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人猴贰,你說我怎么就攤上這事对雪。” “怎么了米绕?”我有些...
    開封第一講書人閱讀 162,632評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵慌植,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我义郑,道長(zhǎng),這世上最難降的妖魔是什么丈钙? 我笑而不...
    開封第一講書人閱讀 58,180評(píng)論 1 292
  • 正文 為了忘掉前任非驮,我火速辦了婚禮,結(jié)果婚禮上雏赦,老公的妹妹穿的比我還像新娘劫笙。我一直安慰自己,他們只是感情好星岗,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評(píng)論 6 388
  • 文/花漫 我一把揭開白布填大。 她就那樣靜靜地躺著,像睡著了一般俏橘。 火紅的嫁衣襯著肌膚如雪允华。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,165評(píng)論 1 299
  • 那天寥掐,我揣著相機(jī)與錄音靴寂,去河邊找鬼。 笑死召耘,一個(gè)胖子當(dāng)著我的面吹牛百炬,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播污它,決...
    沈念sama閱讀 40,052評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼剖踊,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼庶弃!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起德澈,我...
    開封第一講書人閱讀 38,910評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤歇攻,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后圃验,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體掉伏,經(jīng)...
    沈念sama閱讀 45,324評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評(píng)論 2 332
  • 正文 我和宋清朗相戀三年澳窑,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了斧散。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,711評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡摊聋,死狀恐怖鸡捐,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情麻裁,我是刑警寧澤箍镜,帶...
    沈念sama閱讀 35,424評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站煎源,受9級(jí)特大地震影響色迂,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜手销,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評(píng)論 3 326
  • 文/蒙蒙 一歇僧、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧锋拖,春花似錦诈悍、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至柄错,卻和暖如春舷夺,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背鄙陡。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工冕房, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人趁矾。 一個(gè)月前我還...
    沈念sama閱讀 47,722評(píng)論 2 368
  • 正文 我出身青樓耙册,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親毫捣。 傳聞我的和親對(duì)象是個(gè)殘疾皇子详拙,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • 一帝际、事件機(jī)制 事件是在編程時(shí)系統(tǒng)內(nèi)發(fā)生的動(dòng)作或者發(fā)生的事情,系統(tǒng)會(huì)在事件出現(xiàn)的時(shí)候觸發(fā)某種信號(hào)并且會(huì)提供一個(gè)自動(dòng)加...
    RickyWu585閱讀 282評(píng)論 0 0
  • 請(qǐng)描述:什么是捕獲饶辙,什么是冒泡并說一下是先捕獲還是先冒泡 捕獲 捕獲就是由外向內(nèi)蹲诀,從第一層 >> 第二層 >> 第...
    貓的老字號(hào)閱讀 193評(píng)論 0 1
  • 一、DOM事件模型/機(jī)制 示例代碼: 文字 即:.爺爺>.爸爸>.兒子, 給3個(gè)div分別添加事件監(jiān)聽fn...
    大魚JOHN閱讀 383評(píng)論 0 0
  • DOM事件模型/機(jī)制 一個(gè)事件發(fā)生之后弃揽,會(huì)在子元素個(gè)父元素之間進(jìn)行傳播脯爪,這種傳播又分為三個(gè)階段: 事件捕獲:從外向...
    為誰填詞曲為誰_404閱讀 149評(píng)論 0 1
  • DOM 事件流 這里規(guī)定的事件流有三個(gè)階段: 事件捕獲階段,目標(biāo)階段矿微,事件冒泡階段痕慢。 默認(rèn)false 是冒泡階段捕...
    奶油蛋糕好好吃哦閱讀 153評(píng)論 0 0