4

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

$(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").mousedown(htmlMouseDown,myDropDown) 放在 dropDownMouseDown-handler 中,但是一旦冒泡到达 html 元素,它将立即被调用。

4

3 回答 3

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/

于 2013-05-27T15:13:24.643 回答
1

What about using a variable that contains the last openened one ? There are probably many other ways of doing this, but here is a way I could think of:

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

Then:

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
}

That should work in a way that the last opened one always close itself before opening a new one.

于 2013-05-27T14:57:09.373 回答
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();
    }
于 2013-05-27T15:40:06.890 回答