一、事件机制

事件是在编程时系统内发生的动作或者发生的事情,系统会在事件出现的时候触发某种信号并且会提供一个自动加载某种动作的机制(来自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. manual for emacs markdown-mode(English)

    markdown-mode now requires Emacs 24.3 or later. Markup insertion and replacement keybindings under C ...

  2. Vue + Element 实现多选框选项上限提示与限定

    上图先,看效果!!! //vue文件夹内<el-form :model="form" class="form-inline"> <!-- :s ...

  3. functools 中的 reduce 函数基本写法

    reduce 返回的往往是一整个可迭代对象的 操作结果 reduce(函数,可迭代对象) 注:lambda x,y 两个参数 2020-05-04

  4. PHP 中的字符串变量

    PHP 字符串变量 字符串变量用于存储并处理文本. PHP 中的字符串变量 字符串变量用于包含有字符的值. 在创建字符串之后,我们就可以对它进行操作了.您可以直接在函数中使用字符串,或者把它存储在变量 ...

  5. ZROI 提高十连测 DAY2

    总结:入题尽量快,想到做法要先证明是否正确是否有不合法的情况,是否和题目中描述的情景一模一样.    不要慌 反正慌也拿不了多少分,多分析题目的性质如果不把题目的性质分析出来的话,暴力也非常的难写,有 ...

  6. windows:shellcode 原理

    shellcode,一段短小精干的代码,放在任何地方都能执行,不依赖当前所处环境,那么就有这么几点要求: 不能有全局变量:函数里的局部变量在栈空间,地址是执行的时候动态分配的:但全局变量在编译时,会由 ...

  7. MR程序的几种提交运行模式

    本地模式运行 1-在windows的eclipse里面直接运行main方法 将会将job提交给本地执行器localjobrunner 输入输出数据可以放在本地路径下 输入输出数据放在HDFS中:(hd ...

  8. Vue老项目支持Webpack打包

    1.老的vue项目支持webpack打包 最近在学习Vue.js.版本是2.6,webpack的版本也相对较老,是2.1.0版本.项目脚手架只配置了npm run dev和npm run build. ...

  9. artifactdescriptorexception:Failed to read artifact descriptor for xxx:jar ”

    在Eclipse中执行Maven的install命令时,报“Failed to read artifact descriptor for xxx:jar ”的错误.这可能是在下载过程中文件出现错误.或 ...

  10. CSS3 新添选择器

    目录 属性选择器 结构伪类选择器 伪元素选择器 属性选择器 属性选择器可以元素特定属性来进行选择,这样就可以不借助于类选择器或id选择器 选择符 简述 E[att] 选择具有att属性的E元素 E[a ...