一、事件机制

事件是在编程时系统内发生的动作或者发生的事情,系统会在事件出现的时候触发某种信号并且会提供一个自动加载某种动作的机制(来自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. Excel绘制经典图表

    1.柱形图 2.条形图 3.饼图---复合饼图 4.圆环图 5.组合图 设置不同的纵轴 6.漏斗图 其中:合计呈逐渐下降的趋势,可以用漏斗图进行展示! 绘制漏斗图首先需要构建辅助列,在插入图形的时候选 ...

  2. PHP symlink() 函数

    定义和用法 symlink() 函数创建一个从指定名称连接的现存目标文件开始的符号连接. 如果成功,该函数返回 TRUE.如果失败,则返回 FALSE. 语法 symlink(target,link) ...

  3. PHP imagecolorclosestalpha - 取得与指定的颜色加透明度最接近的颜色的索引

    imagecolorclosestalpha — 取得与指定的颜色加透明度最接近的颜色的索引.高佣联盟 www.cgewang.com 语法 int imagecolorclosestalpha ( ...

  4. 使用pdf.js实现前端页面预览pdf文档,解决了跨域请求

    pdf.js主要包含两个库文件,一个pdf.js和一个pdf.worker.js,,一个负责API解析,一个负责核心解析 官网地址:http://mozilla.github.io/pdf.js/ 下 ...

  5. C/C++编程笔记:C++入门知识丨函数和函数模板

    本篇要学习的内容和知识结构概览 函数的参数及其传递方式 1. 函数参数传递方式 传值: 传变量值: 将实参内存中的内容拷贝一份给形参, 两者是不同的两块内存 传地址值: 将实参所对应的内存空间的地址值 ...

  6. Codeforces Round #654 (Div. 2) A~E 题解

    LINK:CF R 654 div2 前言:F题是一个线段树分类讨论的题目 比赛的时候没看 赛后感觉没什么意思 所以咕掉了. 记事:第一次笼统的写一场比赛的题目 可能是我这场比赛打的太差了 题目不难 ...

  7. UOJ #310 黎明前的巧克力 FWT dp

    LINK:黎明前的巧克力 我发现 很多难的FWT的题 都和方程有关. 上次那个西行寺无余涅槃 也是各种解方程...(不过这个题至今还未理解. 考虑dp 容易想到f[i][j][k]表示 第一个人得到巧 ...

  8. 快速构建一个springboot项目(一)

     前言: springcloud是新一代的微服务框架而springboot作为springcloud的基础,很有必要对springboot深入学习一下. springboot能做什么? (1)spri ...

  9. python 操作元组 列表===python中三大宝刀(字典已经再上一遍 说过)

    字典俗称,世界有多大就能装多大 列表俗称,你们决定 元组俗称,可远观而不可亵玩焉 列表的相关操作a=['1','2','3','5','6','7']# print(a[0])# print(a[0: ...

  10. 你该知道的Docker-compose

    Docker-compose介绍 前几篇文章和小伙伴们,分享了使用Dockerfile来构建镜像,使用docker run等命令来手动启动镜像.docker stop停止镜像.docker kill杀 ...