提问人:Brandon 提问时间:7/3/2015 最后编辑:Brian Tompsett - 汤莱恩Brandon 更新时间:4/22/2021 访问量:294
取消 jQuery 侦听器与元素子集的绑定
Unbinding a jQuery listener from a subset of elements
问:
我正在使用 Zurb Foundation 工具提示 (http://foundation.zurb.com/docs/components/tooltips.html)。我想稍微自定义他们的行为。它们利用源元素上的事件侦听器来创建工具提示(在第一次调用时),然后淡入。我试图做的是让jQuery在页面上选择工具提示源的子集,仅删除它们的鼠标悬停侦听器,并绑定新的听证器,让工具提示在那里停留一秒钟,然后在鼠标移开后消失。mouseover
这是棘手的部分。Zurb 按如下方式绑定其侦听器:
$('body.off-canvas').on('mouseenter', '.has-tooltip', ...);
以下命令将按预期成功删除此侦听器:
$('body.off-canvas').off('mouseenter', '.has-tooltip');
但我只想删除其中一些元素的侦听器,如下所示:
$('body.off-canvas').off('mouseenter', '.has-tooltip.my-custom-class');
事实证明,jQuery不会将其视为较大元素集的“减法”,而是说,“没有与此精确选择器匹配的事件侦听器,因此我不会做任何事情。有没有人有一个好的解决方法?我发现如果您自己创建原始侦听器,一些方法会起作用,但这里并非如此。.has-tooltip
答:
我认为,如果您想防止应用于 body 元素的“mouseenter”功能被触发,您可以停止这些锚链接上的事件冒泡。
使用 JQUERY :
$(".has-tooltip.my-custom-class").on("mouseenter", function(event){
event.stopPropagation();
....
....
});
希望对你有所帮助。
评论
我通过采取不同的方法解决了这个问题。我以为我无法删除所有普通工具提示的默认 Foundation 事件,因为我仍然需要 Foundation 来构建工具提示元素。解决方法很棘手,但它完成了工作。
页面加载后,我立即在所有工具提示上手动触发了该事件,使用特殊的 CSS 类强制它们在初始化后保持不可见而不是淡入。我必须模拟事件中的鼠标数据,因为 Foundation 依赖于它来初始定位工具提示。完成 DOM 修改后,我可以将侦听器添加到模拟默认行为的普通工具提示中,同时将自定义侦听器添加到我的自定义元素中。mouseenter
// simulate and trigger default tooltip hover event to allow Foundation to create spans
$('body.off-canvas .has-tip').each(function(){
var event = $.Event('mouseenter');
var offset = $(this).offset();
var position = $(this).position();
event.clientX = offset.left;
event.clientY = offset.top;
//event.offsetX = ;
//event.offsetY = ;
event.pageX = offset.left;
event.pageY = offset.top;
event.screenX = offset.left;
//event.screenY = ;
$(this).trigger(event);
});
$('body.off-canvas .has-tip').trigger('mouseleave');
// remove default events
$('body.off-canvas').off('mouseenter', '.has-tip');
$('body.off-canvas').off('mouseleave', '.has-tip');
// restore normal tooltips to normal behavior
$('body.off-canvas').on('mouseenter', '.has-tip:not(.has-details)', function(){
$('span.tooltip[data-selector="' + $(this).data('selector') + '"]').removeClass('force-visibility-hidden').fadeIn();
});
$('body.off-canvas').on('mouseleave', '.has-tip:not(.has-details)', function(){
$('span.tooltip[data-selector="' + $(this).data('selector') + '"]').fadeOut();
});
// set up custom details tooltip listener
$('body.off-canvas').on('mouseenter', '.has-tip.has-details', function(e){
...
});
顺便说一句,我还必须将整个事情包装在一个 a 中,以确保它在应用基金会监听器后执行。setTimeout(..., 200);
总而言之,这是我写过的最复杂的代码之一,但它就像一个魅力。
可用于停止元素上的所有其他处理程序。由于处理程序是按照添加顺序执行的,因此请确保在添加 Zurb 的代码之前添加代码。下面是一个示例,说明如何测试:stopImmediatePropagation()
my-custom-class
$(function(){
$('body.off-canvas').on('mouseenter', '.has-tooltip', function(event){
if($(event.target).hasClass('my-custom-class')){
event.stopImmediatePropagation();
}
});
});
评论
.filter()
:not()
.my-custom-class
on()