事件冒泡通常如何工作,它是事件传播的同义词吗?


11

我试图围绕事件驱动的(子)系统中事件分配的一般工作原理和原则进行研究。

尽管我曾在很多场合使用过它,例如Javascript,Flash(动作脚本2和3),甚至一次都用PHP编写了一个简单的事件分配系统,但我从未真正理解过事件冒泡和/或很好地传播。

第一个问题:
事件冒泡是事件传播的同义词吗?

第二个问题:
我理解的是,当事件“冒泡”时,这意味着它在对象的层次结构中“移动”了吗?

第三个也是最重要的问题:
如果我对问题2的理解是正确的;通常如何“向上移动”对象的层次结构?
它通常意味着父对象“重新分派”相同的事件,以它的母公司(直到它到达根对象)?如果是这样; 层次结构中的所有这些对象是否需要听这些事件的子对象,还是我对事件冒泡的理解缺少重要的原则,而无需让父对象将自身注册为子对象事件的侦听器?

如果您可以通过一些简单的伪代码来说明这些基本原理,我将不胜感激。


1
相关文章:活动顺序
乔纳斯(Jonas)

Answers:


7

第一个问题:事件冒泡是事件传播的同义词吗?

不可以。冒泡是事件传播的一种形式,但不能用作同义词。传播是传递事件的总称。冒泡是事件传播的一种特定策略。

第二个问题:我理解的是,当事件“冒泡”时,这意味着它在对象层次结构中“移动”了吗?

是。冒泡意味着它沿着层次结构向上移动,而不是隧穿,这意味着它从顶部元素开始向下移动或路由,这意味着接收事件的下一个对象可以是您选择的任何对象。

第三个也是最重要的问题:如果我对问题2的理解是正确的;通常如何“向上移动”对象的层次结构?

相当容易。在您的视觉层次结构中,控件具有对其父级/顶级视觉的引用,或者可以在某处获得。因此,当他们捕获事件时,他们只是将事件通知给它的父项,从而将其通知给父项。

伪代码对于任何UI控件都是这样的:

OnEvent(SomeEvent event)
{
   CallHandlersForEvent(event);
   if(HasParent && event.ContinueBubbling == true)
   {
       Parent.OnEvent(event);
   }
}

就像blueberryfields所说的那样,下次接收事件的不一定是直接的父母。您也可以这样实现:

OnEvent(SomeEvent event)
{
    CallHandlersForEvent(event);
    NextControl = VisualTree.GetVisualParent(this);
    if(NextControl != null && event.ContinueBubbling == true)
    {
       NextControl.OnEvent(event);
    }
}

+1伪代码对我来说很有意义,谢谢!(顺便说一句,其余的答案也一样。)
体面的达伯尔

@fireeyedboy:不客气=)
猎鹰

1

第一个答案:

事件冒泡是一种指导事件传播的特定算法。

第二个答案:

不,冒泡不一定与任何等级有关。在内部或其他地方如何表示对象对于算法能否正常工作并不重要。理想情况下,当事件冒泡时,事件将从屏幕上最里面的可见元素向外扩展到屏幕上最外面的可见元素。

第三个答案:

实现细节可能会有所不同,具体取决于每个(浏览器)内部的实现方式。该bubbling算法取决于屏幕上的视觉效果。例如,如果封装元素在继承层次结构上高于内部元素,则冒泡可以使用该语言中的标准继承机制来实现。但这不一定是正确的-您可能具有专门的机制,可以解释内部结构及其在屏幕上的可见性,并根据算法传播事件,而忽略内部组织。


1
你为什么说:“冒泡不一定与任何等级有关”。我认为是。没有层次,就不会冒泡。必须有某种树。您能举一个没有树结构的冒泡示例吗?您的示例“从最里面到最外面的可见元素”就是这样-视觉层次。
猎鹰

1
当然,如果您确实愿意,可以将其解释为层次结构。我更喜欢将其视为一个松散耦合的图形,其中包含一些视觉和一些非视觉元素。
blueberryfields

2
但是冒泡的类推失败了。因为在图中事件可以被路由到任何地方,而冒泡显然是从底部到顶部。
猎鹰

我认为您再也不能在任意图形中冒泡了。它必须被称为“事件路由”,然后恕我直言。
猎鹰

1
我相信猎鹰会提出一些公平的观点。将冒泡视为向上移动的事物(层次结构),这听起来很合理。
体面的摔跤手
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.