JavaScript 详说事件流(冒泡、捕获、传播、委托)
事件流
事件流描述的是从页面中接收事件的顺序。
标准DOM事件流存在三个阶段:事件捕获阶段、处于目标阶段和事件冒泡阶段。
事件捕获:当触发事件时,浏览器会从根节点开始由外到内进行事件传播,即点击了子元素,如果父元素也绑定了对应事件的话,会先触发父元素绑定的事件。
事件冒泡:与事件捕获恰恰相反,事件冒泡的顺序是由内到外进行事件传播,直到根节点。
无论是事件捕获还是事件冒泡,它们都有一个共同的行为,就是事件传播。
注意:IE低版本不支持事件捕获,所以就少了一个事件捕获阶段,其他浏览器则同时存在。
事件委托:由于事件冒泡的存在,可以把原本想要绑定到子元素上的事件绑定到父元素上,满足条件时触发事件。事件委托用到了event
对象的target
(触发事件的某个具体对象)属性和currentTarget
(绑定事件的对象)属性来区分父元素和子元素。
如何绑定事件
方法一:直接在标签中添加事件属性,事件前面要加on
。
缺点:HTML与JS耦合,不利于维护。还有就是可能存在元素已经渲染但事件代码还未加载,这种情况下触发事件会报错。
<!-- 直接在onclick定义代码 --><div onclick="alert('hello')">click Me</div><!-- 触发一个函数 --><div onclick="alertHello()">click Me</div><script>function alertHello() {alert('hello');}</script>
方法二:是将一个函数赋值给DOM节点的事件属性,事件前面要加on
。
特点:事件处理程序是在元素的作用域中运行,程序中的 this
引用当前元素。
<div id="div">click me</div><script>var div = document.getElementById('div');div.onclick = function () {alert('hello');}//可以通过下面这行代码删除事件//div.onclick = null;</script>
方法三:addEventListener()
接受三个参数:要处理的事件名(不用加on
)、事件处理函数和一个布尔值(可选,默认值为false
,表示事件在冒泡阶段执行,true
表示事件在捕获阶段执行)。
缺点:IE低版本浏览器不支持。
特点:为同一事件定义多个事件处理程序,触发事件时会以添加它们的顺序执行。事件处理程序是在元素的作用域中运行,程序中的 this
引用当前元素。
<div id="div">click me</div><script>var div = document.getElementById('div');function alertHello() {alert('hello');}div.addEventListener('click', alertHello, false);// 可以通过下面这行代码删除事件// div.removeEventListener('click', alertHello, false);// 如果绑定的事件函数是匿名函数,如// div.addEventListener('click', function(){}, false);// 则无法删除事件</script>
方法四:attachEvent()
接受两个参数:事件名(要加on
)与事件处理函数。由于 IE8 及更早版本只支持事件冒泡,所以通过添加的事件处理程序都会被添加到冒泡阶段。
缺点:只能在IE8及更早版本使用。
特点:事件处理程序会在全局作用域中运行,因此 this
等于 window
。为同一事件定义多个事件处理程序,触发事件时不会以添加它们的顺序执行,而是以相反的顺序被触发。
<div id="div">click me</div><script>var div = document.getElementById('div');function alertHello() {alert('hello');}div.attachEvent("onclick", alertHello);// 可以通过下面这行代码删除事件// div.detachEvent('click', alertHello, false);// 如果绑定的事件函数是匿名函数,如// div.attachEvent('click', function(){}, false);// 则无法删除事件</script>
阻止事件冒泡
方法一(推荐):event.stopPropagation();
缺点:IE浏览器无法使用。
<div id="parent"><div id="child">click me</div></div><script>var parent = document.getElementById('parent'),child = document.getElementById('child');parent.addEventListener('click', function() {alert('parent');})child.addEventListener('click', function(e) {alert('child');e.stopPropagation();})</script>
方法二:event.cancelBubble = true;
缺点:只能在IE浏览器使用。
<div id="parent"><div id="child">click me</div></div><script>var parent = document.getElementById('parent'),child = document.getElementById('child');parent.attachEvent('onclick', function() {alert('parent');})child.attachEvent('onclick', function() {alert('child');window.event.cancelBubble = true;})</script>
方法三:event.stopImmediatePropagation()
特点:阻止事件冒泡并且阻止相同事件的其他侦听器被调用。
<div id="parent"><div id="child">click me</div></div><script>var parent = document.getElementById('parent'),child = document.getElementById('child');parent.addEventListener('click', function () {alert('parent');})child.addEventListener('click', function (e) {alert('child');e.stopImmediatePropagation();})child.addEventListener('click', function (e) {alert('hello'); //不会执行})</script>
取消默认事件
方法一(推荐):event.preventDefault()
缺点:IE8及以下版本浏览器不支持。
<a href="https://www.baidu.com" onclick="alert('hello');event.preventDefault();">click me</a>
方法二:event.returnValue = false;
缺点:非标准,兼容性差。
<a href="https://www.baidu.com" onclick="alert('hello');event.returnValue=false;">click me</a>
方法三:return false;
缺点:在addEventListener
注册的事件处理函数中无法阻止事件默认行为。
<a href="https://www.baidu.com" onclick="alert('hello');return false;">click me</a>
事件对象
在触发 DOM 上的某个事件时,会产生一个事件对象 event
,这个对象中包含着所有与事件有关的信息。这个 event
对象会传入到事件处理函数中。
dom.onclick = function (e) {alert(e.type)
}
直接定义在元素上的事件中的变量 event
中保存着 event
对象。
<button onclick="alert(event.type)">click me</button>
属性 | 类型 | 读写 | 描述 |
---|---|---|---|
target
|
Element | 只读 | 事件的目标 |
currentTarget
|
Element | 只读 | 事件处理函数所在的那个元素 |
stopPropagation()
|
Function | 只读 |
取消事件的进一步捕获或冒泡。如果bubbles 为true ,则可以使用这个方法
|
stopImmediatePropagation()
|
Function | 只读 | 取消事件的进一步捕获或冒泡,同时阻止任何相同事件处理程序被调用 |
bubbles
|
Boolean | 只读 | 表明事件是否冒泡 |
preventDefault()
|
Function | 只读 |
取消事件的默认行为。如果cancelable 是true ,则可以使用这个方法
|
cancelable
|
Boolean | 只读 | 表明是否可以取消事件的默认行为 |
defaultPrevented
|
Boolean | 只读 |
为 true 表示已经调用了 preventDefault()
|
type
|
String | 只读 | 被触发的事件的类型 |
eventPhase
|
Integer | 只读 |
调用事件处理程序的阶段:1 表示捕获阶段,2 表示“处于目标”,3 表示冒泡阶段
|
trusted
|
Boolean | 只读 |
为true 表示事件是浏览器生成的。为false 表示事件是由开发人员通过 JavaScript 创建的
|
detail
|
Integer | 只读 | 与事件相关的细节信息 |
view
|
AbstractView | 只读 |
与事件关联的抽象视图。等同于发生事件的window 对象
|
在事件处理程序内部,对象 this
始终等于 currentTarget
的值,而 target
则只包含事件的实际目标。
<div id="parent"><div id="child">clickme</div></div><script>let parent = document.getElementById("parent"),child = document.getElementById("child");parent.addEventListener('click', function(e){console.log(this === parent); //trueconsole.log(e.target === child); //trueconsole.log(e.currentTarget === parent); //true});</script>
IE事件对象
直接定义DOM对象的事件属性,event
对象会作为 window
对象的一个属性存在。
dom.onclick = function(){console.log(window.event.type);
}
如果事件处理程序是使用 attachEvent()
添加的,那么就会有一个 event
对象作为参数被传入事件处理程序函数中。
dom.attachEvent("onclick", function (event) {alert(event.type);
});
直接定义在元素上的事件中的变量 event
中保存着 event
对象。
<button onclick="alert(event.type)">click me</button>
属性 | 类型 | 读写 | 描述 |
---|---|---|---|
cancelBubble
|
Boolean | 读/写 |
默认值为false ,但将其设置为true 就可以取消事件冒泡
|
returnValue
|
Boolean | 读/写 |
默认值为true ,但将其设置为false 就可以取消事件的默认行为
|
srcElement
|
Element | 只读 | 事件的目标 |
type
|
String | 只读 | 被触发的事件的类型 |
因为事件处理程序的作用域是根据指定它的方式来确定的,所以不能认为 this
会始终等于事件目标。故而,最好还是使用 event.srcElement
比较保险。例如:
<div id="parent">clickme</div><script>var div = document.getElementById("parent");div.onclick = function () {alert(window.event.srcElement === this); //true };div.attachEvent("onclick", function (event) {alert(event.srcElement === this); //false alert(this === window); //true });</script>
由于 IE 不支持事件捕获,因而只能取消事件冒泡;但 stopPropagatioin()
可以同时取消事件捕获和冒泡。
JavaScript 详说事件流(冒泡、捕获、传播、委托)相关推荐
- javascript -- 事件--事件流-- 冒泡 --捕获
javascript -- 事件 事件是js和用户操作交互的桥梁, JavaScript 有三种事件模型:内联模型.脚本模型和 DOM2 模型 内联模型 这种模型是最传统接单的一种处理事件的方法.在内 ...
- JavaScript 详说事件机制之冒泡、捕获、传播、委托
DOM事件流(event flow )存在三个阶段:事件捕获阶段.处于目标阶段.事件冒泡阶段. 事件捕获(event capturing):通俗的理解就是,当鼠标点击或者触发dom事件时,浏览器会 ...
- JavaScript 事件(冒泡捕获)处理模型
JavaScript 事件处理模型 (冒泡&捕获) 1.事件处理流程 DOM 结构: html --> body --> div(事件绑定对象) 2. 事件捕获阶段 获取事件触发对 ...
- JavaScript 中的事件流和事件处理程序(读书笔记思维导图)
JavaScript 程序采用了异步事件驱动编程模型.在这种程序设计风格下,当文档.浏览器.元素或与之相关的对象发生某些有趣的事情时,Web 浏览器就会产生事件(event). JavaScript ...
- 针对JavaScript的常用事件、对象捕获和使用技巧
事件源对象 event.srcElement.tagName event.srcElement.type 捕获释放 event.srcElement.setCapture(); event ...
- 事件模型、事件流(冒泡与捕获)、事件代理
本文原链接:https://www.cnblogs.com/hngdlxy143/p/9068282.html https://www.jb51.net/article/139997.htm 事件模型 ...
- js中的DOM事件之冒泡和捕获事件详解
DOM中的事件是一个很中要的东西,它可以让用户和浏览器之间进行交互,以此来实现人机交互效果 DOM事件 DOM事件分为DOM0级事件和DOM2级事件.DOM0级其实不存在,我们把DOM最初的版本叫0级 ...
- html流动模型,javascript的事件流模型都有什么?
事件流:当你在页面触发一个点击事件后,页面上不仅仅有一个元素响应该事件而是多个元素响应同一个事件,因为元素是在容器中的.事件发生的顺序就是事件流,不同的浏览器对事件流的处理不同. JavaScript ...
- 带你理解DOM事件流
在做前端开发的时候,我们经常需要做一些各式各样的交互,如鼠标单击/双击/滑动事件.键盘事件等等等等,这些都是DOM事件.首先我们先看一个概念,叫DOM事件流. DOM事件流 事件流:事件在目标元素和祖 ...
最新文章
- Mac环境下svn的使用
- python项目实例代码-python开源项目及示例代码
- matlab保存数据
- centos6.4下安装python3.6以及对应的django1.11
- Employee Assign Organization unit
- jdk 安装_Jdk 安装使用教程
- linux之修改dns以及用netmask修改ip和网关
- GPU GPGPU
- CentOS 7以yum方式安装zabbix3.2及配置文件详解
- pc端签名 vue 生成图片_Vue Canvas 实现电子签名 手写板
- crontab使用环境变量
- suse 内核编译安装_Linux内核编译与安装
- 如何破解锐捷支持多网卡
- 第一章 Activity的生命周期和启动模式
- vue实现消息badge 标记_vue 新消息提示
- 女神青涩时纤毫毕现,腾讯 AI 模型 GFPGAN 火上 GitHub 热榜第一,Demo 在线可玩
- 智能窗帘控制(光、红外、蓝牙)
- web利用html2canvas实现截图上传图片
- 《Python机器学习》基础代码
- 前端中的hack是什么意思?常见的hack技术以及以及hack技术的利弊
热门文章
- alpine安装更新
- 使用redis分布式锁+lua脚本实现分布式定时任务控制demo
- 通过命令行工具使用阿里云资源编排服务
- 【转载】前端开发之CSS兼容写法经验总结
- Linux之shell编程基础
- vmware虚拟机linux的扩容问题导致redhat无法启动!
- gpedit msc组策略面板 win10在哪里_Win10系统gpedit.msc在哪?Win10系统gpedit.msc组策略打不开怎么办?...
- html 滚动条,菜鸟,ionic 滚动条
- js array 删除指定元素_JS数组
- spyder 怎么看函数定义_看漫画学C++035:自定义函数(1)