JS冒泡、捕获、默认事件那些事

思考

<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">child</div>
    </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">child</div>
    </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规范三个事件阶段

在这里插入图片描述
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也是不会起作用的。

return false

  • 原生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 对象代表事件的状态,比如事件在其中发生的元素、键盘按键的状态、鼠标的位置、鼠标按钮的状态。

事件通常与函数结合使用,函数不会在事件发生前被执行!

在一个事件完成了所有阶段的传播路径后,它的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获取到的就是哪一个元素。

事件对象event的一些兼容性写法

//获得event对象兼容性写法 
event || (event = window.event);

//获得target兼容型写法 
event.target||event.srcElement

//阻止浏览器默认行为兼容性写法 
event.preventDefault ? event.preventDefault() : (event.returnValue = false);

//阻止冒泡写法 
event.stopPropagation ? event.stopPropagation() : (event.cancelBubble = true);

谢谢你阅读到了最后
欢迎点赞评论交流

发布了65 篇原创文章 · 获赞 76 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/weixin_42752574/article/details/103518355