停止特定处理程序的传播

时间:2013-05-27 14:06:07

标签: javascript jquery

假设我有自定义下拉列表()。单击按钮时,我想调出菜单,当用户点击菜单外部时,我希望它关闭。所以我做了这样的事情:

$(myDropDown).mousedown(dropDownMouseDown);
$("html").mousedown(htmlMouseDown,myDropDown);
function dropDownMouseDown(event) {
    event.target.open();
    event.stopPropagation();//I need this line or else htmlMouseDown will be called immediately causing the dropDown-menu to close right before its opened
}
function htmlMouseDown() {
    this.close();
}

嗯,这很有效。但是,如果我添加其中两个呢?如果我点击打开第一个,那么第二个相同然后两个都将打开,因为dropDownMouseDown停止传播,所以htmlMouseDown永远不会被调用第一个。 我该如何解决这个问题? 如果我只有这两个,那么添加一些逻辑当然很容易,但如果数量是动态的?另外我可能不想调用event.stopPropagation(),因为它会对我正在使用的其他库也会有什么奇怪的东西来监听那个事件呢? 我也尝试过这一行: $( “HTML”)。鼠标按下(htmlMouseDown,myDropDown) 在dropDownMouseDown-handler中,但是一旦冒泡到达html元素,它将立即被调用。

3 个答案:

答案 0 :(得分:2)

假设你有一个投影选择器(让我们说“.dropdown”),我会尝试使用'.not()'

$('.dropdown').mousedown(dropDownMouseDown);

$("html").on('mousedown', htmlMouseDown);

function dropDownMouseDown(event) {
    event.target.open();
}

function htmlMouseDown(event) {
  $('.dropdown').not($(event.target)).close();
}

这里有一个与css类相同的小提琴: http://jsfiddle.net/eFEL6/4/

答案 1 :(得分:1)

使用包含最后一个开放变量的变量怎么样?可能有很多其他方法可以做到这一点,但这是我能想到的一种方式:

var lastOpened = null; // initially nothing is open (unless something is)

然后:

function dropDownMouseDown(event) {
    if (lastOpened != null) { // if one is still open
        lastOpened.close(); // close it
        lastOpened = null; // nothing is open anymore
    }

    event.target.open();
    lastOpened = event.target; // now this one is open
    event.stopPropagation();
}

function htmlMouseDown() {
    this.close();
    lastOpened = null; // nothing is open
}

这应该以一种方式起作用,即最后打开的那个在打开一个新的之前总是关闭。

答案 2 :(得分:0)

感谢您的回答。他们真的很感激。我确实找到了一种方法,我很满意。方法如下:

$(myDropDown).mousedown(dropDownMouseDown);
$("html").mousedown(myDropDown,htmlMouseDown);//Pass in the dropDown as the data argument, which can then be accessed by doing event.data in the handler
function dropDownMouseDown(event) {
    event.target.open();
}
function htmlMouseDown(event) {
    if (event.target!=event.data)//event.target is the element that was clicked, event.data is set to the dropdown that this handler was added for. Unless these two elements are the same then we can...
        event.data.close();///close the dropdown this handler was added for
}

无法相信我没想到这一点。在我的情况下,虽然打开/关闭的元素具有子元素,因此event.target可以是子元素之一,而不是处理程序附加到的元素。所以我把我的html-element-handler更改为:

    function htmlMouseDown(event) {
       var element=event.target;
        while (element) {
            if (element==event.data)
                return;
            element=element.parentElement;
        }
        event.data.hide();
    }