【问题标题】:jQuery: Event Bubbling and how "click", "live.click", "stopPropagation", and "return false" work togetherjQuery:事件冒泡以及“click”、“live.click”、“stopPropagation”和“return false”如何协同工作
【发布时间】:2011-05-03 17:20:50
【问题描述】:

我将在这里有情侣场景。请帮帮我

这是基本情况:http://jsfiddle.net/2zsLy/9/

当我点击Click Me 时,警报框和Another Paragraph 都会出现。这是预期的,因为单击事件会冒泡到父容器,即body现在开始我的问题

1)http://jsfiddle.net/2zsLy/10/

为什么将return false 添加到我的live.click 并不能阻止点击事件冒泡。从示例中,live.click 冒泡并触发警报框。我以为文档说 return false 会阻止现场活动冒泡。

2)http://jsfiddle.net/2zsLy/11/

现在,我将 body 中的点击事件更改为 live.click 并解决了问题 -> 点击事件没有冒泡(因此没有显示警告框)。为什么live.click 有效而click 无效。

3)http://jsfiddle.net/2zsLy/13/

我认为文档清楚地表明调用event.stopPropagation() 不会阻止冒泡的发生,我刚刚做到了。我使用event.stopPropagation() 期望它仍然会触发我的警报框,但它不会。为什么?

注意:关于前两个问题的答案,请参见justkt 答案。最后一个问题的答案见Squeegy的回答和他的回复

【问题讨论】:

    标签: jquery


    【解决方案1】:

    您的问题的答案可以在event.stopPropagation() 文档中找到。

    关于 live('click') 与 'click' 和冒泡:

    由于 .live() 方法在事件传播到文档顶部后处理事件,因此无法停止实时事件的传播。同样,由 .delegate() 处理的事件将始终传播到它们被委托的元素;在调用委托的事件处理程序时,它下面的任何元素上的事件处理程序都已经执行。

    所以你看到的是预期的行为。 live('click') 不会停止冒泡。现在首选的.delegate()也是如此。

    This answer 广泛描述了使用 .live 时停止传播的问题。另见.live() 文档:

    事件冒泡直到它到达树的根,这是 .live() 默认绑定其特殊处理程序的地方。

    • 从 jQuery 1.4 开始,事件冒泡可以选择在 DOM 元素“上下文”处停止。

    关于 stopPropagation 本身:

    杀死点击事件的冒泡。

    所以 stopPropagation() 应该防止冒泡无论在哪里返回 false;将,虽然不是它不会。 preventDefault() 不会阻止冒泡。 return false; 实际上是 stopPropagation() 和 preventDefault()。


    响应每个 jsfiddle 示例。

    1) http://jsfiddle.net/2zsLy/10/

    return false; 不会阻止使用livedelegate 绑定的事件冒泡。文档明确说明了所有冒泡,无论是使用return false; 还是使用stopPropagation()。那么会发生什么

    1. 点击<p>
    2. 点击气泡到<body>,触发body.click()
    3. 单击气泡以记录根目录,它与$(event.target).closest('p'); 匹配,因此调用live('click')
    4. 发生返回 false,但在第 2 步调用了正文处理程序

    2) http://jsfiddle.net/2zsLy/11/

    在这种情况下,事件到达同一个位置(文档根目录),并且返回 false 停止传播到通过 live 绑定的进一步事件,该事件位于正文上。

    1. 点击<p>
    2. 点击气泡到<body>,但由于body的处理程序是通过live附加的,它还没有被调用
    3. 单击气泡以记录根目录,它与$(event.target).closest('p'); 匹配,因此调用live('click')
    4. 发生返回错误
    5. live('click') 在 body 上没有被调用,因为返回 false 发生了。

    3)http://jsfiddle.net/2zsLy/13/

    stopPropagation() 明确用于防止冒泡,尽管它具有与 return false; 相同的限制 - 因此,如果有通过 bind 绑定的点击处理程序,它不会在 live('click') 事件的情况下阻止它.

    【讨论】:

    • 我认为你根本没有回答我的问题。你只是引用我不知道的文档。对于每个场景,我都包含 jsfiddle 来演示我的问题。请参考他们。
    • @Harry - 我已经编辑了我的答案以解决每个 jsfiddle 示例。
    • 非常感谢。您对12 的回答给了我很大的帮助。但是,对于3,并不是说你错了,但这是来自 jQuery 网站To stop further handlers from executing after one bound using .live(), the handler must return false. Calling .stopPropagation() will not accomplish this. 的引用 从上面,Squeegy3 做出了回答和一些评论,你同意他的回答吗? 3, justkt?
    • @Harry - 我相信您引用的部分是指同一 DOM 对象上的其他处理程序(因此另一个处理程序绑定到 p),必须使用 return false 或 @ 停止987654360@(隐式调用stopPropegation)。 See this bug report 当它因为我这么认为的原因而被打破时。我认为 Squeegy 是对的。
    • @Harry - 你将 jQuery 设置为 1.4.3。将其设置为 1.4.4 或更高版本,然后查看该错误是否已修复。请注意该错误报告中的一条评论:Unfortunately calling stopImmediatePropagation() doesn't work in 1.4.3 for live handlers, but this has already been fixed and will work once 1.4.4 comes out. 如果您升级版本,您会发现这是真的。
    【解决方案2】:
    1. 实时事件总是在绑定事件之后发生(例如调用click(fn))。所以 return false 在这里什么都不做,因为$("body").click() 已经发生了。这是由于冒泡。单击发生在您单击的元素的每个父级上,触发每个单击事件。只有当它冒泡到根文档时,才会触发任何实时事件。

    2. 在此示例中,您有 2 个实时事件。因此事件会冒泡到文档中,并且 jQuery 开始运行它找到的与您的点击匹配的任何实时事件。当它收到return false 时,它会停止运行任何其他实时事件。直播活动先声明,先运行。所以你得到了新的段落,但没有别的,因为在p 实时点击之后,警报被添加到实时事件堆栈中。

    3. 它不会停止绑定事件的传播,但event 参数实际上是一个jQuery 事件包装对象,我相信它知道live。因此,它具有与返回 false 类似的效果,它会阻止文档单击处理程序执行任何其他实时事件。

    【讨论】:

    • 12 的好答案。我不确定我是否理解您对3 的回答。所以event.stopPropagation() 没有停止传播,是什么停止传播,Squeegy?
    • 它停止了横向传播,而不是垂直传播。 $('p').live('click', fn)click 处理程序绑定到文档。一次单击可能会发生多个实时事件,因为该单击处理程序循环遍历所有已注册的实时事件并尝试将您提供的选择器与启动事件的元素相匹配。如果有匹配项,它将运行您的函数。 event.stopPropagation() 告诉 jQuery 提前中止该循环。因此,您并没有停止事件的冒泡,而是停止document 的点击处理程序查找click 的任何其他元素。
    猜你喜欢
    • 2011-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-11
    • 2011-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多