如何使用 jquery live 停止事件冒泡?

IT技术 javascript jquery dom event-delegation
2021-03-09 18:44:15

我试图停止一些事件,但 stopPropagation 不适用于“live”,所以我不知道该怎么做。我在他们的网站上找到了这个。

实时事件不会以传统方式冒泡,并且无法使用 stopPropagation 或 stopImmediatePropagation 停止。例如,以两个点击事件为例——一个绑定到“li”,另一个绑定到“li a”。如果在内部锚点上发生点击,则将触发两个事件。这是因为当 $("li").bind("click", fn); 绑定您实际上是在说“每当 LI 元素上或 LI 元素内发生单击事件时,都会触发此单击事件。” 要停止对直播事件的进一步处理,fn 必须返回 false

它说 fn 必须返回 false 所以我试图做的

 $('.MoreAppointments').live('click', function(e) {
   alert("Hi");
   return false;
 });

但这不起作用,所以我不知道如何让它返回 false。

更新

这里有更多信息。

我有一个表格单元格,并将点击事件绑定到它。

 $('#CalendarBody .DateBox').click(function(e)
    {
        AddApointment(this);
    });

所以 AddApointment 只是制作了一些 ui 对话框。

现在实时代码(MoreAppointments)位于这个表格单元格中,基本上是一个锚标签。因此,当我单击锚标记时,它首先转到上面的代码(addApointment - 所以首先运行该事件)运行该代码,但不启动我的对话框,而是直接转到(MoreAppointment)事件并运行该代码。该代码运行后,它会从“addApointment”启动对话框。

更新 2

这是一些html。我没有复制整个表格,因为它有点大,而且所有的单元格都用相同的数据重复。如果需要我会发布它。

 <td id="c_12012009" class="DateBox">
        <div class="DateLabel">
            1</div>
        <div class="appointmentContainer">
            <a class="appointments">Fkafkafk fakfka kf414<br />
            </a><a class="appointments">Fkafkafk fakfka kf414<br />
            </a><a class="appointments">Fkafkafk fakfka kf414<br />
            </a><a class="appointments">Fkafkafk fakfka kf414<br />
            </a><a class="appointments">Fkafkafk fakfka kf414<br />
            </a>
        </div>
        <div class="appointmentOverflowContainer">
            <div>
                <a class="MoreAppointments">+1 More</a></div>
        </div>
    </td>
6个回答

简短的回答很简单,你不能

问题

通常,您可以阻止事件“冒泡”到外部元素上的事件处理程序,因为内部元素的处理程序首先被调用然而,jQuery 的“实时事件”的工作原理是将所需事件的代理处理程序附加到文档元素,然后在事件使文档冒泡后调用适当的用户定义处理程序

冒泡的插图
(来源:shog9.com

这通常使“实时”绑定成为一种相当有效的绑定事件的方法,但它有两个很大的副作用:首先,任何附加到内部元素的事件处理程序都可以防止“实时”事件为自身或其任何子元素触发;其次,“实时”事件处理程序不能阻止直接附加到文档子项的任何事件处理程序触发您可以停止进一步的处理,但您不能对已经发生的处理做任何事情......并且当您的实时事件触发时,直接附加到孩子的处理程序已经被调用

解决方案

您最好的选择(据我从您发布的内容来看)是对两个点击处理程序使用实时绑定。完成后,您应该能够return false.MoreAppointments处理程序中阻止.DateBox处理程序被调用。

例子:

$('.MoreAppointments').live('click', function(e) 
{
  alert("Hi");
  return false; // prevent additional live handlers from firing
});

// use live binding to allow the above handler to preempt
$('#CalendarBody .DateBox').live('click', function(e)
{
   AddApointment(this);
});
哇这太有道理了。现在我必须选择最佳答案,您的答案解释了 live 如何与事件冒泡一起工作并提供解决方案。或者 gnarf 解决方案不需要修改我的代码并且也能工作,但在未来的情况下现在可能会工作。
2021-05-13 18:44:15
event.stopPropagation 也提到了这一点:api.jquery.com/event.stopPropagation
2021-05-18 18:44:15

我使用过这种 if 代码并且它对我有用:

$('#some-link').live('click', function(e) {
    alert("Link clicked 1");
    e.stopImmediatePropagation();
});

$('#some-link').live('click', function(e) {
    alert("Link clicked 2");    
});

所以,在我看来,现在 JQuery 支持带有实时事件的 stopImmediatePropagation

也许您可以检查一下a元素上是否没有发生 click 事件

$('#CalendarBody .DateBox').click(function(e) {
  // if the event target is an <a> don't process:
  if ($(e.target).is('a')) return;

  AddApointment(this);
});

可能有用吗?

@Codemonkey -是的,它是......event.target在被点击的实际的事情,总是在那里点this将会是.DateBox-你绑定的事件太容器。
2021-04-22 18:44:15
这似乎有效,只是需要对其进行更多测试。但是我想知道是否可能存在这样一种情况,即点击事件本身就是一个锚标记,并且它会阻止自己调用其余的代码。但话说回来,我对这个目标一无所知,所以这可能根本不是问题。
2021-05-08 18:44:15
出于好奇,这行:if ($(this).is('a')) return;与您答案中的有什么不同吗?
2021-05-15 18:44:15

我正在使用这个:

if(event.target != this)return; // stop event bubbling for "live" event
$('#some-link').live('click', function(e) { if(e.target != this)return; }
2021-05-13 18:44:15

我用

e.stopPropagation(); // to prevent event from bubbling up
e.preventDefault(); // then cancel the event (if it's cancelable)