jQuery - 如果我在div内部点击,不要隐藏它

3

如果我在当前的div内点击,我希望它保持可见状态。只有在页面上但不是当前div中任何位置单击时,我才想隐藏该div。

我已经尝试过e.stopPropagation();,但这会破坏我在函数内部拥有的其他单击处理程序。

jsFiddle

var filterContainer = $(".js-filter-container");
var pageDocument = $(document);

$(document).on('click', '.js-show-filter', function(e) {
    e.preventDefault();

    var currentFilter = $(this).next(filterContainer);
    currentFilter.toggle().css("z-index", 99);
    filterContainer.not(currentFilter).hide();

    pageDocument.click(function(){
        filterContainer.hide();
    });

    return false;
});

1
你想要隐藏一个div,但是当你点击同样的div时,你又想让它显示出来。你怎么能点击一个被隐藏的东西呢? - 8protons
3
@8protons不,他希望在用户点击内部时保持元素可见,并在用户点击外部任何地方时隐藏它。 - Rory McCrossan
@RoryMcCrossan:“当元素被点击时保持可见”,这意味着“在内部点击时不执行任何操作”。我的意思是,如果你的div在你点击它时可见,并且在你点击它时仍然可见,那么你并没有“保持它可见”,而是“什么也没做”。 - 8protons
4个回答

3

如果你不想改变事件传播,你可以通过从事件目标向上遍历来检查点击是否在元素内,即$(e.target).closest()。(仅检查事件目标本身无法处理子元素。)此处显示的示例绑定到特定元素而不是委托文档事件,但它将完全相同地工作:

$('.catch').click(function(e) {
  if ($(e.target).closest('.prevent').length) {
    // The click was somewhere inside .prevent, so do nothing
  } else {
    alert("Hide the element");
  }
});
.prevent {
  border: 1px solid
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="catch">
  Clicks here should fire the event.
  <div class="prevent">
    Clicks here should not fire the event.
    <div class="whatever">Neither should <b>clicks</b> on <i>child nodes</i>.</div>
    And not here.
  </div>
  But here, yes.
</div>


1
通过尝试在同一次遍历中处理打开和关闭器,往往会使事情变得过于复杂。已在https://jsfiddle.net/2pr3xtxf/30/修复。 - Daniel Beck
顺便提一下,要小心在“document”上挂太多的委托事件处理程序——当它们开始相互干扰时,会使您的代码变得复杂;而且会导致浏览器触发太多不必要的事件。唯一需要在“document”上的事件是关闭弹出窗口的事件,这个事件应该只在弹出窗口打开后绑定(然后在弹出窗口关闭时解除绑定)……其余的应该直接绑定到打开链接,或者至少绑定到一个更近的父元素。 - Daniel Beck

0

有两种方法: 最简单的方法:在点击div时,调用e.stopPropagation(),并复制您想要的所有点击处理程序(不是正确的方法,因为您会重复代码...)

或者在您的onclick函数中,获取光标位置,并仅在光标位置不在div内部时关闭div:

pageDocument.click(function(e)
{
    //we get element position
    var startX = $(filterContainer).offset().left;  
    var startY = $(filterContainer).offset().top;

    var endX   = startX + $(filterContainer).outerWidth();
    var endY   = startY + $(filterContainer).outerHeight();

    //mouse pose relative to page (not window)
    var mouseX  = e.pageX;
    var mouseY  = e.pageY;


    if (!((mouseX > startX || mouseX < endX) && (mouseY > startY || mouseY < endY))) filterContainer.hide(); //if not on the container: remove it
});

你的第二个选项是最佳选择。 - dokgu
我也尝试了第二个选项,但它仍然不起作用-https://jsfiddle.net/2pr3xtxf/27/ - brunodd
好的,我更新了fiddle,它现在工作得更好了...(你没有给函数传递'e'参数,而且你还忘记在onclick的开始处删除(filterContainer).hide()。但问题是每次点击时,你都声明一个新的处理程序,所以你会重复这些操作...这不是最好的方法。你真的想在body点击时关闭它吗? - Vincent

0

你可以尝试这种方法

$(document).on('click', '.js-show-filter', function(e) {
    $('.currentFilter').removeClass('currentFilter');
    var currentFilter = $(this).next('.js-filter-container');
    $('.js-filter-container:visible').hide();
    currentFilter.addClass('currentFilter');
    currentFilter.slideDown(500);
});

$('body').on('click', ':not(.currentFilter)', function(){
    $('.currentFilter').removeClass('currentFilter');
    $('.js-filter-container:visible').hide();
});

在这里试一下

查看这个W3Schools的手风琴教程


0

最终我采用了这个解决方案:

$(document).mouseup(function (e) {
    if (!filterContainer.is(e.target) && filterContainer.has(e.target).length === 0) {
       filterContainer.hide();
    }
});

{{link1:jsFiddle}}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接