1.什么是事件流?javascript
事件流所描述的是从页面中接受事件的顺序css
2.DOM事件流的三个阶段?html
事件流包括三个阶段:事件捕获阶段、处于目标阶段、事件冒泡阶段java
3.DOM事件流三个阶段的执行顺序?浏览器
首先发生的事件捕获,为截取事件提供机会,而后是目标接受事件,最后是事件冒泡阶段,因此能够在最后一个阶段对事件做出响应。见下图更直观:bash
在dom事件流中,事件的目标在捕获阶段不会接受到事件,这意味着在捕获阶段,事件从 document 到 div 后就中止了。下一个阶段是目标阶段,因而事件在 div 上发生,并在事件处理中被当作是冒泡阶段的一部分, 而后,冒泡阶段发生,事件又传回document。
dom
1.什么是事件冒泡?
当事件发生后,这个事件就要开始传播(从里向外或者从外向里)函数
2.为何要传播?ui
由于事件源自己(可能)并无处理事件的能力,即处理事件的函数(方法)并未绑定在该事件源上。例如咱们点击一个按钮时,就会产生一个click事件,但这个按钮自己可能不能处理这个事件,事件必须从这个按钮传播出去,从而到达可以处理这个事件的代码中(例如咱们给按钮的onclick属性赋一个函数的名字,就是让这个函数去处理该按钮的click事件),或者按钮的父级绑定有事件函数,当该点击事件发生在按钮上,按钮自己并没有处理事件函数,则传播到父级去处理。spa
小案例代码以下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Document</title>
</head>
<body>
<div>
<button>点击</button>
</div>
</body>
</html>
复制代码
(1) button
(2) div
(3) body
(4) html
(5) document
1.为何要阻止冒泡?
例如:document上有A事件,div有B事件,div里面的span有C事件,若是不给span和div加阻止事件冒泡的话,点击span时就会触发到div的B事件、document的A事件,当点击span时不想触发div和document的事件就要加上阻止事件冒泡,div也是同样的道理,若是咱们不想让点击某个事件时父级受到影响,这时就应阻止冒泡。
eg:不加阻止冒泡事件,代码以下:
css代码:
<style type="text/css">
.box1{width:200px;height:200px;background:pink;}
.box2{width:100px;height:100px;background:gray;}
</style>复制代码
js+html代码:
<body>
<div class="box1">
<div class="box2"></div>
</div>
<script type="text/javascript">
//获取对象
var box1 = document.getElementsByClassName('box1')[0];
var box2 = document.getElementsByClassName('box2')[0];
//添加事件
box1.onclick = function(){
console.log('您点击了box1');
}
box2.onclick = function(){
console.log('您点击了box2');
}
</script>
</body>复制代码
效果以下:
如图能够看出当点击 box1 时,只会提示‘您点击了box1’ 而点击 box2 时,居然输出了两句提示,若是咱们不想要这种效果,咱们只想要在点击了哪一个按钮后就执行该按钮的命令,也就是说阻止冒泡。
下面给出上述小案例的阻止冒泡方法:一句代码搞定,改变 box2 的触发事件,代码以下:
box2.onclick = function(e){
console.log('您点击了box2');
e.stopPropagation();
}复制代码
效果图以下:这样就实现阻止冒泡
2.阻止冒泡的方法。
①event.stopPropagation()方法 (这个方法小编在上面已经给出了例子,这里就不在给出具体的例子)
这是阻止事件的冒泡方法,不让事件向documen上蔓延,可是默认事件仍然会执行,当你调用这个方法的时候,若是点击一个链接,这个链接仍然会被打开,
②event.preventDefault()方法
这是阻止默认事件的方法,调用此方法是,链接不会被打开,可是会发生冒泡,冒泡会传递到上一层的父元素;
下面给你们一个小例子:看图说话,在下面的空白处,不管我怎么点击右键,不管在什么位置点击,都会出现默认的东西,若是咱们不想要这种默认的东西怎么办呢?继续看图下面的案例,立刻带你飞,走起-------
eg:阻止浏览器右键默认事件
css代码:
<style type="text/css">
*{margin:0;padding:0;}
ul{list-style:none;}
.box{position:relative;width:80px;border:1px solid gray;display: none;}
.box ul li{height:40px;line-height:40px;text-align:center;}
.box ul li:hover{background:#ccc;}
</style>复制代码
html+js代码:
<body>
<div class='box'>
<ul>
<li>刷新</li>
<li>删除</li>
<li>命名</li>
</ul>
</div>
<script type="text/javascript">
//获取box对象
var box = document.getElementsByClassName('box')[0];
//右键鼠标事件
window.oncontextmenu = function(event){
//阻止默认事件
event.preventDefault();
//获取鼠标点击某个位置的水平位置 X 和垂直位置 Y
var x=event.clientX;
var y=event.clientY;
//改变 box 距离上面和左边的位置
box.style.top = y + 'px';
box.style.left = x + 'px';
box.style.display = 'block';
}
window.onclick = function() {
box.style.display = "none";
}
</script>
</body>
复制代码
效果以下:
③ return false(这里的例子就不赘述了,有心的小伙伴能够动手试试)
这个方法比较暴力,他会同时阻止事件冒泡也会阻止默认事件;写上此代码,链接不会被打开,事件也不会传递到上一层的父元素;能够理解为return false就等于同时调用了event.stopPropagation()和event.preventDefault()
事件捕获和事件冒泡是恰好相反的,事件捕获是指不太具体的节点应该更早的接收到事件,而最具体的节点应该最后接收到事件
案例走起:
css代码:
<style type="text/css">
.box1{width:300px;height:300px;background:pink;}
.box2{width:200px;height:200px;background:skyblue;}
.box3{width:100px;height:100px;background:gray;}
</style>复制代码
html+js代码:
<body> <div class="box1">
<div class="box2">
<div class="div box3"></div>
</div>
</div>
<script type="text/javascript">
//获取对象
var box1 = document.getElementsByClassName('box1')[0];
var box2 = document.getElementsByClassName('box2')[0];
var box3 = document.getElementsByClassName('box3')[0];
//点击事件
box1.addEventListener('click',function(){
console.log("捕获 box1");
},true);
box2.addEventListener('click',function(){
console.log("捕获 box2");
},true);
box3.addEventListener('click',function(){
console.log("捕获 box3");
},true);
</script>
</body>复制代码
动态效果以下:
当我点击最里面的 box3 时,咱们能够看到最外层的事件先被触发,最后才是咱们点击的 box3 事件被触发,这即是事件捕获。