0

我试图在单击按钮时创建覆盖,然后在用户单击覆盖外部时将其删除。在我的示例中,当单击叠加层时,目标返回长度为“0”,我无法弄清楚为什么当此方法与我使用过的其他示例一起使用时。任何的想法?

这是js

$(document).ready(function() {
    $(document).on("click",".pop", function() {
       if ($('#search-overlay').length === 0) {
           $('body').append('<div id="search-overlay"></div>');
        }
    });
    $(document).on("mouseup", function(e) {
      var container = $("#search-overlay");
      if (container.has(e.target).length === 0) {
        alert(container.has(e.target).length);
        container.remove();
      }
    });
});

以及您在其中看到它的链接http://jsfiddle.net/CwrAh/

4

1 回答 1

3

那是因为.has()寻找后代,它与 jQuery 对象内部的元素不匹配。一项额外的检查来修复您的逻辑:

if (!container.has(e.target).length && !container.is(e.target)) {

小提琴

考虑到性能时,您可以将函数替换为元素与jQuery 对象中包含的第一个元素is()之间的简单比较:e.targetcontainer

 if (!container.has(e.target).length && container[0] !== e.target) {

小提琴#1.1


您还可以进一步简化它.closest()

if (!$(e.target).closest(container).length) {

小提琴 #2

相同的逻辑,但反过来。closest开始尝试匹配包含在 jQuery 对象中的元素,并向上遍历 DOM 树寻找匹配的祖先覆盖。结果与第一个版本相同。


第三个变体,它放弃了逻辑测试的需要。附加一个 mouseup 处理程序,停止事件传播到覆盖,因此它不会到达document

$('body').append($('<div>', {
    id: 'search-overlay',
    mouseup: function(e) {
        e.stopPropagation();
   }
}));

小提琴#3

于 2013-02-17T00:27:12.083 回答