<style>
div {
padding: 20px;
}
.grandparent {
background: orange;
}
.parent {
background:#eee;
}
.child {
background: red;
}
style>
<div class="grandparent">
grandparent
<div class="parent">parent
<div class="child">childdiv>
div>
div>
<script>
let grandparent =document.querySelector('.grandparent')
let parent =document.querySelector('.parent')
let child =document.querySelector('.child')
grandparent.addEventListener('click', ()=> {console.log('grandparent')}, false)
parent.addEventListener('click', ()=> {console.log('parent')}, false)
child.addEventListener('click', ()=> {console.log('child')}, false)
script>
点击child块,依次打印出了
child
parent
grandparent
点击parent块,依次打印出了
parent
grandparent
点击grandparent块,只打印出了
grandparent
addEventListener第三个参数false改为true
<style>
div {
padding: 20px;
}
.grandparent {
background: orange;
}
.parent {
background:#eee;
}
.child {
background: red;
}
style>
<div class="grandparent">
grandparent
<div class="parent">parent
<div class="child">childdiv>
div>
div>
<script>
let grandparent =document.querySelector('.grandparent')
let parent =document.querySelector('.parent')
let child =document.querySelector('.child')
grandparent.addEventListener('click', ()=> {console.log('grandparent')}, true)
parent.addEventListener('click', ()=> {console.log('parent')}, true)
child.addEventListener('click', ()=> {console.log('child')}, true)
script>
点击child块,依次打印出了
grandparent
parent
child
点击parent块,依次打印出了
grandparent
parent
点击grandparent块,只打印出了
grandparent
W3C规范中定义了3个事件阶段,依次是捕获阶段
、目标阶段
、冒泡阶段
。事件对象按照上图的传播路径依次完成这些阶段。如果某个阶段不支持或事件对象的传播被终止,那么该阶段就会被跳过。
举个例子,如果Event.bubbles属性
被设置为false
,那么冒泡阶段就会被跳过
。如果Event.stopPropagation()
在事件派发前被调用,那么所有的阶段都会被跳过。
捕获阶段
:
在事件对象到达事件目标之前,事件对象必须从window经过目标的祖先节点传播到事件目标
。
这个阶段被我们称之为捕获阶段。在这个阶段注册的事件监听器在事件到达其目标前必须先处理事件
。
目标阶段
:
事件对象到达其事件目标。 这个阶段被我们称为目标阶段。
一旦事件对象到达事件目标,该阶段的事件监听器就要对它进行处理。如果一个事件对象类型被标志为不能冒泡。那么对应的事件对象在到达此阶段时就会终止传播。
冒泡阶段
:
事件对象以一个与捕获阶段相反的方向
从事件目标传播经过其祖先节点传播到window。
这个阶段被称之为冒泡阶段。在此阶段注册的事件监听器会对相应的冒泡事件进行处理。
addEventListener()
绑定事件,第三个参数默认为false,也就是冒泡
,如果为true;则为捕获
任何发生在w3c事件模型中的事件,首是进入捕获阶段,直到达到目标元素,再进入冒泡阶段
我们可以选择是在捕获阶段还是冒泡阶段绑定事件处理函数,这是通过addEventListener()方法实现的,如果这个函数的最后一个参数是true,则在捕获阶段绑定函数,反之false,在冒泡阶段绑定函数。默认为false;
w3c的方法是e.stopPropagation(),IE则是使用e.cancelBubble = true
stopPropagation也是事件对象(Event)的一个方法,作用是阻止目标元素的冒泡事件,但是会不阻止默认行为。什么是冒泡事件?如在一个按钮是绑定一个”click”事件,那么”click”事件会依次在它的父级元素中被触发 。stopPropagation就是阻止目标元素的事件冒泡到父级元素。
终止事件
在传播过程的捕获、目标处理或起泡阶段进一步传播
。调用该方法后,该节点上处理该事件的处理程序将被调用,事件不再被分派到其他节点。
w3c的方法是e.preventDefault(),IE则是使用e.returnValue = false;
preventDefault它是事件对象(Event)的一个方法,作用是取消一个目标元素的默认行为。既然是说默认行为,当然是元素必须有默认行为才能被取消,如果元素本身就没有默认行为,调用当然就无效了。什么元素有默认行为呢?如a标签(默认行为是跳到指定页面),提交按钮(默认行为是提交表单信息)等。
当Event 对象的 cancelable为false时,表示没有默认行为,这时即使有默认行为,调用preventDefault也是不会起作用的。
原生javascript的return false
只会阻止默认行为jQuery中的return false
既阻止默认行为又防止对象冒泡。function test(event) {
//获得event对象兼容性写法
let event = event || (event = window.event);
//获得target兼容型写法
let target = event.target || event.srcElement
//阻止浏览器默认行为兼容性写法
event.preventDefault ? event.preventDefault() : (event.returnValue = false);
//阻止冒泡写法
event.stopPropagation ? event.stopPropagation() : (event.cancelBubble = true);
}
注意点:
firefox里的event(事件对象)跟IE里的不同,IE里的是全局变量,随时可用;firefox里的要用参数引导才能用,是运行时的临时变量。
在IE/Opera中是window.event,在Firefox中是event;而事件的对象,在IE中是window.event.srcElement,在Firefox中是event.target,Opera中两者都可用。
function a(e){
var e = (e) ? e : ((window.event) ? window.event : null);
// 或者
var e = e || window.event; // firefox下window.event为null, IE下event为null
}
Event 对象代表事件的状态,比如事件在其中发生的元素、键盘按键的状态、鼠标的位置、鼠标按钮的状态。
事件通常与函数结合使用,函数不会在事件发生前被执行!
在一个事件完成了所有阶段的传播路径后,它的Event.currentTarget会被设置为null并且Event.eventPhase会被设为0。Event的所有其他属性都不会改变(包括指向事件目标的Event.target属性).
javascript文档上有关event标准属性的介绍:
属性 | 描述 |
---|---|
bubbles | 返回布尔值,指示事件是否是起泡事件类型。 |
cancelable | 返回布尔值,指示事件是否可拥可取消的默认动作。 |
currentTarget | 返回其事件监听器触发该事件的元素。 |
eventPhase | 返回事件传播的当前阶段。 |
target | 返回触发此事件的元素(事件的目标节点)。 |
timeStamp | 返回事件生成的日期和时间。 |
type | 返回当前 Event 对象表示的事件的名称。 |
currentTarget
:
currentTarget 事件属性返回其监听器触发事件的节点,即当前处理该事件的元素、文档或窗口。
通俗一点说,就是你的点击事件绑定在哪一个元素上,currentTarget获取到的就是哪一个元素。
target
:
target 事件属性可返回事件的目标节点(触发该事件的节点),如生成事件的元素、文档或窗口。
通俗一点说,就是你当前点击的是哪一个元素,target获取到的就是哪一个元素。
MDN文档-CustomEvent.detail
MDN文档-UIEvent.detail
UIEvent.detail是只读属性, 当值为非空的时候, 提供当前连续点击次数
(和环境有关) 。 点击一次为1,连续点击两次为2
通过代码比如事件对象e.click()触发点击事件时为0
对 click 或者 dblclick 事件, UIEvent.detail 是当前点击数量。
对 mousedown 或者 mouseup 事件, UIEvent.detail是1加上当前点击数。
对所有的其它UIEvent 对象, UIEvent.detail 总是零.
接口 CustomEvent 的只读属性 detail (详情)
返回在初始化事件对象时传递过来的任何类型数据
。
CustomEvent() 用于创建一个自定义事件。
// add an appropriate event listener
obj.addEventListener("cat", function(e) { process(e.detail) });
// create and dispatch the event
let event = new CustomEvent("cat", {
detail: {
hazcheeseburger: true
}
});
obj.dispatchEvent(event);
// Will return an object contaning the hazcheeseburger property
let myDetail = event.detail;
//获得event对象兼容性写法
event || (event = window.event);
//获得target兼容型写法
event.target||event.srcElement
//阻止浏览器默认行为兼容性写法
event.preventDefault ? event.preventDefault() : (event.returnValue = false);
//阻止冒泡写法
event.stopPropagation ? event.stopPropagation() : (event.cancelBubble = true);
谢谢你阅读到了最后
欢迎点赞
、评论
、交流