JavaScript:事件流
事件流
事件流是对事件执行过程的描述,了解事件的执行过程有助于加深对事件的理解,提升开发实践中对事件运用的灵活度。
如上图所示,任意事件被触发时总会经历两个阶段:【捕获阶段】和【冒泡阶段】。
简言之,捕获阶段是【从父到子】的传导过程,冒泡阶段是【从子向父】的传导过程
事件流涉及到三个主要的概念:事件捕获阶段、目标阶段和事件冒泡阶段。了解这些阶段和相关的属性对于理解事件流的机制至关重要。
事件捕获
事件捕获阶段是事件流的第一个阶段,从根节点开始向下传播到目标元素。在事件捕获阶段中,事件依次经过每个父元素,直到达到目标元素。
在事件捕获阶段,可以使用addEventListener的第三个参数指定事件处理程序在捕获阶段中执行。
上图的例子中,事件处理顺序是Window=>Document=>box1=>box2=>a。除此之外,我们还可以观察到:事件捕获只发生在被点击的元素或目标上,该事件不会传播到子元素。
我们用到了addEventListener方法,在一般情况下,该方法只会用到两个参数,一个是需要绑定的事件,另一个是触发事件后要执行的函数,但是,addEventListener还可以传入第三个参数,该参数默认值是false,表示在事件冒泡阶段调用事件处理函数;如果该参数为true,则表示在事件捕获阶段调用处理函数。
<script>
window.addEventListener("click",()=>{
console.log("Window");
},true);
document.addEventListener("click",()=>{
console.log("Document");
},true);
document.querySelector("#box2").addEventListener("click",()=>{
console.log("box2");
},true);
document.querySelector("#box1").addEventListener("click",()=>{
console.log("box1");
},true);
document.querySelector("a").addEventListener("click",()=>{
console.log("Click me");
},true);
</script>
事件冒泡
事件冒泡和事件捕获是完全相反的。事件冒泡是由内到外的,它是从目标节点开始,沿父节点依次向上,并触发父节点上的事件,直至文档根节点,就像水底的气泡一样,会一直向上。如下图。
上图的例子中,事件处理顺序是Window<=Document<=box1<=box2<=a。
上面我们说到,addEventListener的第三个参数默认值是false,表示在事件冒泡阶段调用事件处理函数,这说明事件监听器默认监听冒泡事件。
<script>
window.addEventListener("click",()=>{
console.log("Window");
},false);
document.addEventListener("click",()=>{
console.log("Document");
},false);
document.querySelector("#box2").addEventListener("click",()=>{
console.log("box2");
},false);
document.querySelector("#box1").addEventListener("click",()=>{
console.log("box1");
},false);
document.querySelector("a").addEventListener("click",()=>{
console.log("Click me");
},false);
</script>
阻止事件捕获和事件冒泡
在我们了解事件捕获和事件冒泡后,难免会思考一个问题:如果我们在某个节点上绑定了一个事件,我们需要在点击时触发这个事件,但是由于事件冒泡,这个节点的事件被它的子元素触发了,我们应该怎么阻止这种情况发生呢?
我们可以使用stopPropagation()方法来阻止这种情况发生,它将阻止事件沿着DOM树向上或向下进一步传播。
<script>
window.addEventListener("click",(e)=>{
console.log("Window");
e.stopPropagation();
},false);
document.addEventListener("click",(e)=>{
console.log("Document");
e.stopPropagation();
},false);
document.querySelector("#box2").addEventListener("click",(e)=>{
console.log("box2");
e.stopPropagation();
},false);
document.querySelector("#box1").addEventListener("click",(e)=>{
console.log("box1");
e.stopPropagation();
},false);
document.querySelector("a").addEventListener("click",(e)=>{
console.log("Click me");
e.stopPropagation();
},false);
</script>
鼠标经过事件
mouseover 和 mouseout 会有冒泡效果
mouseenter 和 mouseleave 没有冒泡效果 (推荐)
事件委托
事件委托的原理是:不给每个子节点单独设置事件监听器,而是把事件监听器设置在其父节点上,让其利用冒泡的原理影响到每一个子节点。简而言之,就是不给子元素注册事件,给父元素注册事件,让处理代码在父元素的注册事件上执行
<body>
<ul>
<li>我是第1个小li</li>
<li>我是第2个小li</li>
<li>我是第3个小li</li>
<li>我是第4个小li</li>
<li>我是第5个小li</li>
</ul>
<script>
var ul=document.querySelector('ul')
ul.addEventListener('click',function(e){
e.target.style.backgroundColor='pink'
console.log('1111')
})
</script>
</body>
原文地址:https://blog.csdn.net/2401_86036532/article/details/143799422
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!