【问题标题】:Why do we need event.stopPropagation() in DOM? Is it bad architectural pattern?为什么我们在 DOM 中需要 event.stopPropagation()?它是糟糕的架构模式吗?
【发布时间】:2016-06-08 09:17:09
【问题描述】:
在日常前端开发中,我经常使用 DOM 作为全局事件总线,客户端应用程序的每个部分都可以访问它。
但在我看来,其中有一个“特性”可以被认为是有害的:任何侦听器都可以阻止传播通过此“总线”发出的事件。
所以,我想知道,这个功能什么时候有用。允许一个听众“禁用”所有其他听众是否明智?如果该听众没有对此类行动做出正确决定所需的所有信息怎么办?
更新
这不是关于“什么是冒泡和捕获”或“Event.stopPropagation 实际如何工作”的问题。
这是关于“允许任何订阅者影响事件流的好解决方案”的问题吗?
【问题讨论】:
标签:
dom
design-patterns
architecture
frontend
event-bus
【解决方案1】:
我们需要(我说的是当前在 JS 中的用法)stopPropagation() 当我们想要防止听众相互干扰时。但是,这不是强制性的。
避免stopPropagation的实际原因:
使用它通常意味着您知道代码在等待相同的事件,并干扰当前侦听器的工作。如果是这种情况,那么可能(见下文)这里存在设计问题。我们尽量避免在多个不同的地方管理同一件事。
可能有其他侦听器在等待相同类型的事件,而不会干扰当前侦听器的工作。在这种情况下,stopPropagation() 可能会成为问题。
但是,假设您在容器元素上放置了一个魔法侦听器,每次点击都会触发以执行一些魔法。魔术听众只知道魔术,而不知道文档(至少在魔术之前不知道)。它做一件事。在这种情况下,让它只知道魔法是一个很好的设计选择。
如果有一天您需要阻止特定区域中的点击触发这种魔法,因为将特定于文档的区别暴露给魔法侦听器是不好的,那么防止在其他地方传播是明智的。
一个更好的解决方案可能是(我认为)有一个单独的侦听器来决定它是否需要调用魔法函数,而不是魔法函数是一个可停止的侦听器。这样一来,您就可以保持清晰的逻辑,而不会暴露任何内容。
提供(我说的是API设计)订阅者影响流量的方式没有错;这取决于此功能的需求。它可能对使用它的开发人员有用。例如,stopPropagation 已经(并且现在)对很多人都非常有用。
一些系统实现continueX 方法而不是stopX。在 JavaScript 中,当被调用者可能执行一些异步处理(如 AJA* 请求)时,它非常有用。但是,它不适用于 DOM,因为 DOM 需要及时的结果。我认为stopPropagation 是 DOM API 的明智设计选择。