Javascript事件冒泡机制的详细介绍 浏览:654

1。事件



在浏览器客户端应用程序平台中,基本生命是事件驱动的,即发生事件,然后做出相应的动作。



浏览器事件是事件发生的信号。事件的详细描述不是本文的重点。谁也不了解的朋友可以访问w3school教程的理解,这将有助于更好地理解以下内容。



2。泡沫形成机理



什么是泡沫



下面的图片你应该理解它,从底部的气泡开始上升,从深到浅,上升到顶部。在上升的过程中,气泡将通过不同深度的水。





相应地,这个气泡相当于我们的事件,而水相当于我们的整个DOM树。事件从DOM树的底层传输到DOM的根节点。



简单的案例分析



下面通过一个简单的例子来说明气泡箱的原理:

在这三个简单的DOM元素定义一个HTML格式:DIV1,跨度,格式,含跨,DIV1含有格式;他们都在体:







这是一个跨度。






接口原型如下所示:





在此基础上,我们实现以下功能:



a.body添加点击事件的监测,当身体捕获事件的事件,它打印出来的事件和触发事件的节点信息的时间:





在window.onload =函数(){
document.getelementbyid(体),AddEventListener(单击
}
功能EventHandler(事件){
console.log(:+新的日期(事件时间戳)+节点产生的事件:+ +event.target.id当前节点:+事件。currentTarget。ID);
}




当我们点击这是跨度反过来,格式,DIV1,体,输出以下信息:





对以上结果进行了分析。



无论是身体,身体的子元素的子元素或DIV DIV1,格式,和跨度,当这些元素被点击点击,会发生单击事件,和身体将被捕获,然后相应的事件处理函数会被调用。喜欢从下到上泡在水里,事件会放弃。



事件传输的示意图如下所示:





一般情况下,事件传递过程中存在一些信息。这些是事件的组成部分:事件发生的时间、事件发生的地点、事件的类型、事件的当前处理器以及其他信息。







完整的HTML代码如下所示:







在这里插入标题

{。1
边境:绿色40px固体;
宽度:300px;
身高:300px;
保证金:汽车;
}

{。箱
边境:黄40px固体;
宽度:220px;
身高:220px;
保证金:汽车;
}

{跨度
职位:相对;
左:50px;
上图:50px;
背景颜色:RGBA(128, 128, 128,0.22);
}



在window.onload =函数(){
document.getelementbyid(体),AddEventListener(单击
}
功能EventHandler(事件){
console.log(:+新的日期(事件时间戳)+节点产生的事件:+ +event.target.id当前节点:+事件。currentTarget。ID);
}






这是一个跨度。








B.终止事件的泡沫



我们现在要实现这一功能,当DIV1点击,弹出你好,我是最外层的div 。



所以我们有以下Javascript片段:





在window.onload =函数(){
document.getelementbyid(1)。AddEventListener(单击
警报(你好,我是最外层的div );
});
document.getelementbyid(箱)AddEventListener(单击。
警报(你好,我是学二层);
});
document.getelementbyid(跨越)。AddEventListener(单击
警告(你好,我是。);
});
}




当上面的代码单击跨越时,会弹出一个弹出框,你好,我是是的,它会弹出这样一个对话框:







但是,不仅会生成这个对话框,而且当单击确定时,接下来的对话框会依次弹出:







这显然不是我们想要的!我们想要的是谁显示信息,为什么会发生这种情况呢原因是事件的爆发。当单击跨时,跨将引发事件。DIV1,这是父节点和祖父节点的联赛,也将获得这一事件,那么它会回应事件进行响应的功能。现在的问题是找到了,但是你怎么解决呢



方法1:让我们考虑一个画面:水中的气泡从底部向上上升,而现在你在水中,不想让气泡上升。我们该怎么办-把它刺破!没有气泡,自然不会上升。同样,对于一个节点,如果它不希望它正在处理的事件继续冒泡,我们就可以终止这个气泡:



在相应的处理函数,event.stoppropagation()添加到终止事件的广播分配,这样的事件仍然在节点不会被传染了。修改脚本片段以上:





在window.onload =函数(){
document.getelementbyid(1)。AddEventListener(单击
警报(你好,我是最外层的div );
event.stoppropagation();
});
document.getelementbyid(箱)AddEventListener(单击。
警报(你好,我是学二层);
event.stoppropagation();
});
document.getelementbyid(跨越)。AddEventListener(单击
警告(你好,我是。);
event.stoppropagation();
});
}




在这样的代码之后,单击不同的元素将有不同的提示,并且不会有多个框。

方法二:事件包含初始触发事件的节点引用和当前处理的事件节点的引用。如果节点只处理事件本身,不是事件本身不process.event.target指DOM节点生成事件的对象,而event.currrenttarget指当前处理节点。我们可以使两个目标相等。



例如,跨度单击事件生成事件事件对象。Event.target指出了SPAN元素。当跨度过程这一事件,event.currenttarget还指出,跨元。判断它们之间的平等时,执行相应的处理函数,当事件被传递到event.currenttarget成为格式,格式。那时,两个变量不相等。就是说,事件不是由格式本身产生的,但不应对处理逻辑。





在window.onload =函数(){
document.getelementbyid(1)。AddEventListener(单击
如果(event.target =事件。currentTarget)
{
警报(你好,我是最外层的div );
}
});
document.getelementbyid(箱)AddEventListener(单击。
如果(event.target =事件。currentTarget)
{
警报(你好,我是学二层);
}
});
document.getelementbyid(跨越)。AddEventListener(单击
如果(event.target =事件。currentTarget)
{
警告(你好,我是。);

}
});
}




比较:

从事件传递的角度来看,一种方法是取消事件冒泡,也就是说,当一些节点取消冒泡时,事件不会再次传输。方法二是防止气泡过滤,并过滤需要处理的事件。

利弊:

一个缺点是,为了实现特定元素的点击来显示相应的信息,该方法要求每个元素的子元素也必须终止事件的气泡传递,即与其他元素的函数有很强的相关性。这种方法将是非常脆弱的。例如,如果span元素的处理函数不执行泡沫终止,活动将通过对格式,这将导致格式的提示信息;

方法缺点:另一种方法是,每个元素增加事件处理函数,事件的处理逻辑是非常相似的,而如果(event.target =事件。currentTarget),这些代码的存在是多余的,现在三元就行了,当有10,成百上千的什么怎么办呢

每个元素也有一个处理函数,这在一定程度上增加了逻辑和代码的复杂性。

让我们再分析一下方法二:方法二的原理是事件是否满足事件发生后的要求,然后进行相应的处理,然后事件继续向上冒泡。

由于事件冒泡,能使一事件一致父节点处理,确定发生的事件发生,那是由事件产生的节点,然后作出相应的处理。答案是肯定的,通过添加一个事件监视器的体元,然后判断event.target然后产生不同的行为在不同的目标。



重构方法的两个代码:





在window.onload =函数(){
document.getelementbyid(体),AddEventListener(单击
}
功能eventperformed(事件){
VaR目标= event.target;
开关(目标id){
案例跨度:
警告(你好,我是。);
打破;
案例联赛:
警报(你好,我是学二层);
打破;
案例格式:
警报(你好,我是最外层的div );
打破;
}
}




结果会点击不同的元素,只会弹出匹配的提示,不会有额外的提示。

通过上述方法,我们把每个元素的一些处理功能,都交给爷爷结体元素来完成,也就是说,跨度,格式,DIV1将委托其响应体的逻辑,从而完成相应的逻辑,你没有实现相应的逻辑,这种模式就是所谓的事件委托。



下面是示意图:



关于事件代理的问题,我们将在以后继续讨论。

谢谢你的阅读。我希望你能帮助你,谢谢你对这个站的支持。

标签: 电脑技巧

推荐文章1
广告