为什么听点击没有以正确的顺序执行?

时间:2016-06-14 02:32:24

标签: javascript jquery

我有一个顶级栏图标系统,如Facebook(朋友,消息,通知),我想检查用户是否点击了图标,然后显示与该图标相关的框,如果点击页面上的其他位置,则隐藏盒子。要做到这一点,我必须始终听取文档中的所有点击,并检查点击是否在框外或图标然后隐藏框。而且我不想总是听取文档中的所有点击次数#34;。因此,为了降低性能,我只是在用户点击图标后开始侦听文档中的点击,并且在用户点击图标或框外的其他位置后我停止侦听文档。

现在的问题是,我希望下面的代码检测图标上的点击然后开始收听文档中的所有点击用户点击了另一个图标,然后停止收听文档中的所有点击,然后重新开始此过程。

//this function just checks if the click was outside an element
//http://stackoverflow.com/questions/1403615/use-jquery-to-hide-a-div-when-the-user-clicks-outside-of-it
function clicked_outside(element, e){
        return !element.is(e.target) && element.has(e.target).length === 0;
}
$('.icon').on('click', function(e){
        var object = $(this);
        var box = object.find('.box');
        box.show();
        console.log('start listening for all html clicks outside the element (the icon and the box)');
        $('html').on('click', function(e){
                if (clicked_outside(object, e)){
                        box.hide();
                        console.log('stop listening for all html clicks');
                        $('html').off('click');
                }
        });
});

代码检测到图标上的点击然后开始侦听文档中的所有点击如果用户点击了其他图标<<> / strong>然后它开始再次收听文档中的所有点击,然后停止收听文档中的所有点击

为什么收听点击的次数没有按照正确的顺序执行?

很抱歉,如果我的解释令人困惑且很长,我发誓我尽了最大努力,这是一个jsfiddle来帮忙。

2 个答案:

答案 0 :(得分:0)

更新了小提琴,不确定你想要什么。

var handler = function(e){
  if (clicked_outside(object, e)){
    box.hide();
    console.log('stop listening for all html clicks');
    $('html').off('click', handler);
  }
};
$('html').on('click', handler);

https://jsfiddle.net/dbjon4p5/1/

答案 1 :(得分:0)

您遇到问题的原因是事件的运作方式。它们从您单击的元素开始,它们沿着dom向上运行,直到它们再次遇到父级或某些javascript停止传播。因此,在您的代码中,您始终可以启动下一个框,然后才能停止上一个框的单击。

尝试this来解决这个问题。也不要使用&#34; object&#34;等词语。作为变量名称。它可能会产生非常奇怪的结果。

function clicked_outside(element, e){
        return !element.is(e.target) && element.has(e.target).length === 0;
}
var obj = null;
$('.icon').on('click', function(e){
        if(obj){
            obj.find('.box').hide();
            $('html').off('click');
        }
        obj = $(this);
        var box = obj.find('.box');
        box.show();
        console.log('start listening for all html clicks outside the element (the icon and the box)');
        $('html').on('click', function(e){
                if (clicked_outside(obj, e)){
                        box.hide();
                        console.log('stop listening for all html clicks');
                        $('html').off('click');
                }
        });
});

这是另一种不开始/停止聆听的方式。

function clicked_outside(element, e){
        return !element.is(e.target) && element.has(e.target).length === 0;
}
var obj = null;
$('.icon').on('click', function(e){
        if(obj){
            obj.find('.box').hide();
        }
        obj = $(this);
        obj.find('.box').show();            
});

$('html').on('click', function(e){
    if (obj && clicked_outside(obj, e)){
            obj.find('.box').hide();
            obj = null;
    }
});