一、事件机制

事件是在编程时系统内发生的动作或者发生的事情,系统会在事件出现的时候触发某种信号并且会提供一个自动加载某种动作的机制(来自MDN)。
每个事件都有事件处理器(有时也叫事件监听器),也就是触发事件时运行的代码块。严格来说事件监听器监听事件是否发生,然后事件处理器对事件做出反应。

二、DOM事件流

事件传播是一种机制,用于定义事件如何传播或通过DOM树传播,事件传播有两种方式:事件捕获(Capture)和事件冒泡(Bubble)。
事件传播形式上有三个阶段:

  • 捕获阶段:从窗口进入事件目标阶段
  • 目标阶段: 目标阶段
  • 冒泡阶段:从事件目标回到窗口

但是,目标极端在现代浏览器中没有单独处理,所以当一个事件发生在具有父元素的元素上时,现代浏览器运行两个不同的阶段 - 捕获阶段和冒泡阶段。

三、事件捕获

事件发生时,在捕获阶段,事件从窗口向下通过DOM树传播到目标节点,即从最外层元素(祖先元素)触发事件响应函数,逐级往下,直到目标元素。(从外到内)
如果目标元素的任何祖先(即父、祖父等)和目标本身具有针对该类型事件专门注册的捕获事件侦听器,则这些侦听器将在捕获阶段执行。

四、事件冒泡

在事件冒泡阶段,正好相反。
事件冒泡模式流程:事件发生时,先触发目标元素(最直接元素)的事件响应函数,然后触发其父元素的事件响应函数,并逐级上溯到祖先元素。(从内到外)

五、W3C事件模型

因为有捕获和冒泡两种传播方式,W3C制定了一个标准可以让我们自己选择使用哪种传播方式addEventListener('click',fn,?)
第三个参数?是一个bool值,决定使用捕获或者冒泡。
当你addEventListener函数第三个参数为true时就表示你使用的是事件捕获。父级元素先触发,子级元素后触发。
当你addEventListener函数第三个参数为空或为false时就表示你使用的是事件冒泡。子级元素先触发,父级元素后触发。

六、target vs currentTarget

e.target   用户操作的元素
   e.currentTarget    程序员监听的元素
   this是e.currentTarget,不推荐使用
例:
div>span{文字},用户点击文字
e.target就是span
this是e.currentTarget就是div

七、阻止事件传播

在嵌套的元素中,并且每个元素都有事件处理程序时,当单击内部元素,所有处理程序都将同时执行,因为事件会出现在DOM树中。
为了防止这种情况,可以使用**event.stopPropagation()**方法停止事件冒泡。

<div id="div1" style="border: 1px solid red; width: 100px; height: 100px;">
<div id="div2" style="border: 1px solid blue; width: 50px; height: 50px;"></div>
</div> <script>
hi.addEventListener("click", function(){
console.log('div1')
}); hello.addEventListener("click", function(e){
console.log('div2')
e.stopPropagation()
});
</script>

因为在子元素点击事件中使用了event.stopPropagation()阻止冒泡事件,所以最终只打印出了目标元素'div2',父元素的'div1'并没有被打印出。

八、阻止默认事件

有些事件具有与之关联的默认操作。例如点击一个链接浏览器带你到链接的目标,点击一个表单提交按钮浏览器提交表单等等。
可以使用事件对象的preventDefault()方法来防止此类默认操作。但是,阻止默认操作并不会停止事件传播,事件像往常一样继续传播到DOM树。

<a id='div1' href='https://baidu.com'>点击跳转</a>

<script>
a.addEventListener("click", function(e){
e.preventDefault();
});
</script>

我们给a添加点击事件,当用户点击点击跳转就阻止a标签的默认事件,所以点击后不会有跳转。

九、是否可以阻止冒泡

并不是所有事件都可以阻止冒泡的,具体可以MDN搜索scroll event,看到BubblesCancelable
Bubbles的意思是该事件是否冒泡
Cancelable的意思是开发者是否可以阻止冒泡

event.target & event.currentTarget

  • e.target 指向事件触发的元素
  • e.currentTarget 指向事件绑定的元素

十、事件委托

事件委托就是利用事件冒泡,只指定一个事件处理程序,就可以管理某一类型的所有事件。
事件委托:不监听元素 C 自身,而是监听其祖先元素 P,然后判断 e.target 是不是该元素 C(或该元素的子元素)
阻止默认动作:e.preventDefault() 或者 return false
阻止冒泡:e.stopPropagation()

优点:

省监听数,减少内存消耗

<div id="div1">
<button>click 1</button>
<button>click 2</button>
<button>click 3</button>
<button>click 4</button>
<button>click 5</button>
</div> <script>
div1.addEventListener('click', (e)=> {
//把目标元素赋给t
const t = e.target
// 判断是否匹配目标元素
if (t.tagName.toLowerCase() === 'button') {
console.log('button内容是:' + t.textContent);
}
});
</script>

可以监听动态元素(不存在的元素)

<div id="div1">
</div>
<script>
setTimeout(()=>{
//div1里面添加一个button
const button = document.creatElement('button')
button.textContent = 'click 1'
div1.appendChild(button)
},1000) div1.addEventListener('click',(e)=>{
const t=e.target
if (t.tagName.toLowerCase() ==='button'){
console.log('button被click')
}
});
</script>

封装事件委托

<div id="div1">
</div>
<script>
setTimeout(()=>{
const button = document.creatElement('button')
button.textContent = 'click 1'
div1.appendChild(button)
},1000) on('click','#div1','button',()=>{
console.log('button被点击了')
}) function on(eventType, element, selector, fn){
//判断如果element不是元素
if(!(element instanceof Element)){
element = document.querySelector(element)
}
element.addEventListener(eventType,(e)=>{
const t = e.target
//matches判断一个元素是否满足一个选择器
if(t.matches(selector)){
fn(e)
}
})
}
</script>

DOM 事件机制&事件委托的更多相关文章

  1. DOM事件机制(事件捕获和事件冒泡和事件委托)

    内容: 1.事件复习 2.事件冒泡与事件捕获 3.事件委托 1.事件复习 (1)事件 事件是用来处理响应的一个机制,这个响应可以来自于用户(点击, 鼠标移动, 滚动), 也可以来自于浏览器 下面的链接 ...

  2. [JS]笔记12之事件机制--事件冒泡和捕获--事件监听--阻止事件传播

    -->事件冒泡和捕获-->事件监听-->阻止事件传播 一.事件冒泡和捕获 1.概念:当给子元素和父元素定义了相同的事件,比如都定义了onclick事件,点击子元素时,父元素的oncl ...

  3. js事件机制——事件冒泡和捕获

    概念:当给子元素和父元素定义了相同的事件,比如都定义了onclick事件,点击子元素时,父元素的onclick事件也会被触发.js里称这种事件连续发生的机制为事件冒泡或者事件捕获. IE浏览器:事件从 ...

  4. qt事件机制---事件范例

    在笔记qt课程04笔记中

  5. Atitit  数据库的事件机制--触发器与定时任务attilax总结

    Atitit  数据库的事件机制--触发器与定时任务attilax总结 1.1. 事件机制的图谱1 2. 触发器的类型2 3. 实现原理 After触发器 Vs Instead Of触发器2 3.1. ...

  6. JavaScript 详说事件机制之冒泡、捕获、传播、委托

    DOM事件流(event  flow )存在三个阶段:事件捕获阶段.处于目标阶段.事件冒泡阶段. 事件捕获(event  capturing):通俗的理解就是,当鼠标点击或者触发dom事件时,浏览器会 ...

  7. DOM事件机制进一步理解

    <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name ...

  8. dom事件机制系列

    JS事件流机制 一个完整的JS事件流是从window开始,最后回到window的一个过程,事件流被分为三个阶段: (1~5)捕获过程.(5~6)目标过程.(6~10)冒泡过程. 通过addEventL ...

  9. DOM事件机制

    前言 本文主要介绍DOM事件级别.DOM事件模型.事件流.事件代理和Event对象常见的应用,希望对你们有些帮助和启发! 本文首发地址为GitHub博客,写文章不易,请多多支持与关注! 一.DOM事件 ...

随机推荐

  1. PHP preg_quote() 函数

    preg_last_error 函数用于转义正则表达式字符.高佣联盟 www.cgewang.com 语法 string preg_quote ( string $str [, string $del ...

  2. ABC 162 F Select Half dp 贪心

    LINK:Select Half 考试的时候调了一个小时给调自闭了 原来是dp的姿势不太对. 首先 容易发现 奇数最多空2个位置 偶数最多空1一个位置 然后 设f[i][j][k]表示第i个数选了没有 ...

  3. 一个Java方法能使用多少个参数?

    我最近给我fork的项目QuickTheories增加了一个接口: @FunctionalInterface public interface QuadFunction<A, B, C, D, ...

  4. 【NOIP2017】跳房子 题解(单调队列优化线性DP)

    前言:把鸽了1个月的博客补上 ----------------- 题目链接 题目大意:机器人的灵敏性为$d$.每次可以花费$g$个金币来改造机器人,那么机器人向右跳的范围为$[min(d-g,1),m ...

  5. TF上架模式是什么?有什么作用?

    TF上架模式中的TF上架就是TestFlight上架的意思,意思就是将开发者开发完成的App在苹果官方内测商店TestFlight上架的模式,一般被我们简称为TF上架模式. 为什么要了解TF上架呢?为 ...

  6. json&pickle&shelve

    之前我们学习过用eval内置方法可以将一个字符串转成python对象,不过,eval方法是有局限性的,对于普通的数据类型,json.loads和eval都能用,但遇到特殊类型的时候,eval就不管用了 ...

  7. 数据结构进阶:ST表

    简介 ST 表是用于解决 可重复贡献问题 的数据结构. 什么是可重复贡献问题? ​ 可重复贡献问题 是指对于运算 \(\operatorname{opt}\) ,满足 \(x\operatorname ...

  8. Python制作AI贪吃蛇,很多很多细节、思路都写下来了!

    前提:本文实现AI贪吃蛇自行对战,加上人机对战,读者可再次基础上自行添加电脑VS电脑和玩家VS玩家(其实把人机对战写完,这2个都没什么了,思路都一样) 实现效果: 很多人学习python,不知道从何学 ...

  9. 一篇文章教会你用Python爬取淘宝评论数据(写在记事本)

    [一.项目简介] 本文主要目标是采集淘宝的评价,找出客户所需要的功能.统计客户评价上面夸哪个功能多,比如防水,容量大,好看等等. 很多人学习python,不知道从何学起.很多人学习python,掌握了 ...

  10. Django Web 测试

    Django 单元测试 模拟浏览器发起请求,测试 web 功能.只是简单记录一下怎么使用. 环境 Win10 Python2.7 Django 1.8.11 MySQL5.6 项目结构 大致如下 my ...