【问题标题】:Is it possible to stop child click events propagating to parents when handled by .live()?.live() 处理时是否可以阻止子点击事件传播给父母?
【发布时间】:2011-11-01 00:53:03
【问题描述】:

我的图片和内容上有“背板”:http://syndex.me 所以基本上,你点击一张图片,它会在点击的内容上方覆盖一个信息面板。

我想做两件事:

  • 点击网站背景可以淡出当前打开的信息面板
  • 能够在信息面板点击标签、链接或社交图标,而不会触发它的父功能,这又太淡出了。

我不能对被父点击取代的子点击使用 stopPropagation,因为我需要由 .live() (see documentation) 处理点击事件这是因为帖子是动态加载的。

我不能只说: $("#Background").click(function(){//淡出信息板} 因为整个帖子包装都涵盖了这一点,我不能把事件放在帽子上,因为那样我就更深陷于父母接管儿童事件的困境中:-)

到目前为止,我至少能够只打开一个信息板(即,我单击一个图像,然后单击另一个图像,它将关闭已经打开的图像,并打开当前的图像。所以这部分都很好:

    $('.theContent:not(.clicked)').live("click", function () {
            $(this).children('.postInfo').fadeIn(400);
            $(".clicked").each(function() {
                    $(this).find('.postInfo').fadeOut(400);
                    $(this).removeClass('clicked');
            });
        $(this).addClass("clicked");
 });
     $('.clicked').live("click", function () {
            $(".clicked").each(function() {
                $(this).find('.postInfo').fadeOut(400);
                $(this).removeClass('clicked');
            });
 });

重新 .live()、.delegate() 和 .stopPropogation():

由于 .live() 方法在事件传播到文档顶部后处理事件,因此无法停止实时事件的传播。同样,由 .delegate() 处理的事件将传播到它们被委托的元素;在调用委托的事件处理程序时,绑定在 DOM 树中它下面的任何元素上的事件处理程序将已经执行。因此,这些处理程序可能会阻止委托处理程序通过调用 event.stopPropagation() 或返回 false 来触发。

【问题讨论】:

  • 我不确定它是否有效,但您是否在 live() 事件处理程序上尝试过 return false;
  • 不,只是现在做了,没有任何区别。不过,那将是严肃的禅宗!
  • 在“普通”JavaScript 中,这就是你应该做的 :) 似乎没有办法阻止该事件。你有没有想过设置一个全局变量并在你的动画处理程序上检查它?
  • 我以前从未这样做过,同时我将研究全局变量。我确信这是一个常见的问题。最近很多用户界面都有这种点击外部点击内部方法。
  • 嗯....知道为什么会这样吗? jsfiddle.net/Quincy/PbxBH/2

标签: html jquery nested


【解决方案1】:

简单地检查事件是否真的发生在特定元素上怎么样:

function activate(el) {
    el.find('.postInfo').fadeIn(400);
    el.addClass('clicked');
}
function deactivate(el) {
    el.find('.postInfo').fadeOut(400);
    el.removeClass('clicked');
}
$('.theContent:not(.clicked)').live('click', function(e) {
    deactivate($('.clicked'));
    activate($(this));
});

$('.clicked').live("click", function(e) {
    if (! $(e.target).is('a')) {
        // this should not trigger if a click occured on one of the links
        deactivate($(this));
    }
});

$('#ape').click(function(e) {
    if ($(e.target).is('#ape')) {
        deactivate($('.clicked'));
    }
});

【讨论】:

  • 我想你忘了添加el.addClass('clicked'); 方面,这是表示,好的,我已被点击的标记。我假设你把它放在激活函数中,如果是这样,它会自行取消:syndex.me。确认。
  • @RGBK 是的,我忘记了那条线,我不得不恢复停用/激活呼叫。我已经更新了代码,试试看。
  • 这解决了问题,我错过了倒转电话,谢谢。但它仍然不会停用父级。我想知道,也许是因为目标还不准确?我目前正在研究目标以更好地理解它,这似乎是一个有用的功能。
  • 背景也是一样的,所以我一开始没有包含代码。我现在添加了一个处理程序,它也应该处理这个问题。
  • 您知道吗,我很高兴在信息面板之外单击将其关闭。你怎么看?然后我不必担心.clicked 不起作用(仍然没有)我跟踪了当我点击说心形图标时被点击的元素,它说“div”。这可能是因为它嵌套在许多其他元素中。不过那里有一个。我认为这就足够了。谢谢!
【解决方案2】:

你有没有想过binding动态加载帖子时的点击事件?这样你就可以使用 stopPropagation()。

http://jsfiddle.net/rkw79/CzEj5/

【讨论】:

  • 等等,我认为 bind 不处理未来的元素,只处理当前的元素?不过我会试试看。
  • 就像我认为 bind 无法识别新加载的内容,它来自另一个脚本。
  • @RGBK,啊。如果内容是从您无法控制的脚本加载的,则不能使用此方法。您可以控制 HTML 吗?您始终可以在动态内容周围包裹一个 div 并在此处捕获点击。
【解决方案3】:

如果您将事件绑定到父元素,它不会停止向其子元素传播事件。

您有两种解决方案,将一个事件绑定到每个孩子并在其中放置停止传播调用,或者只是测试谁触发了父母中的点击事件。我觉得第二种解决方案更优雅。

您可以在此处阅读更多相关信息: http://redfishmemories.blogspot.it/2014/08/jquery-prevent-event-propagation-and.html

【讨论】:

    猜你喜欢
    • 2019-01-02
    • 2011-03-19
    • 2014-06-29
    • 1970-01-01
    • 1970-01-01
    • 2019-06-19
    • 2021-07-01
    • 1970-01-01
    • 2020-05-06
    相关资源
    最近更新 更多