事件处理程序的优先级

时间:2013-02-17 19:41:31

标签: javascript jquery events handlers operator-precedence

我不确定这是不是一个好问题,但我很乐意听到一些意见。

想象一下有两种事件:

A: a mouse click
B: mouse is currently inside a box

另外,想象一下有两种事件处理函数:

f: console.log("mouse is clicked")
g: console.log("mouse is clicked inside the box")

现在我想要的代码是,当鼠标单击任何地方但在框内时,显示消息“鼠标被点击”。但是,当在框内单击鼠标时,显示消息“在框内单击鼠标”。

我目前的实施方式如下:

if (A) then {f()}
if (A and B) then {g()}

简而言之,我将f注册为A的监听器,并创建了一个新的事件,当A和B都持有时触发,并且注册了该事件的监听器。

当然,当在框内点击鼠标时,我收到两条消息: “在框内点击鼠标” “鼠标点击”

而不是我正在寻找的单个“鼠标在盒子内”。

是否有正式的方法来定义正在发生的事情,以及解决问题的最佳方法是什么?简而言之,我希望事件处理程序g优先于处理程序f,这样当调用g时它会抑制f的调用。

2 个答案:

答案 0 :(得分:2)

您需要阅读的内容是jQuery中的事件冒泡和传播。

jQuery事件处理程序回调将作为参数传递给事件对象。这包含一个方法,可以调用该方法来停止事件传播,或者“冒泡”到任何父处理程序。

对于您的示例,这意味着您可以将事件绑定到窗口/整个文档以“单击鼠标”,然后将事件绑定到只有“在框内单击鼠标”的框 - 但是停止此事件从达到父处理程序。

$(body).click(function() {
    console.log("mouse is clicked");   
});

$("#box").click(function(e) {
    e.stopPropagation();
    console.log("mouse is clicked inside the box");
});

在父处理程序(事件冒泡)

更具体地说,处理程序本身没有父/子关系 - 它们只是直接绑定到DOM元素。父/子关系是DOM元素本身。

在此示例中,#boxbody元素的子元素(尽管可能包含其中的其他元素)。当在#box上触发单击时,将检查处理程序的元素,然后检查元素的父级,然后检查元素的父级的父级等......一直到DOM树。这将继续,直到事件停止冒泡或达到树的顶部。

通过这种方式,您可以在框中添加另一个元素并添加另一个处理程序来执行相同的操作,即#button - 如果您停止传播事件,则#box或{{会出现1}}消息。

答案 1 :(得分:1)

这可以通过一个事件监听器来实现:

window.addEventListener('click', function (e) {
    if (document.getElementById('box').contains(e.target)) {
        alert('Box clicked!');
    } else {
        alert('Not box clicked!');
    }
}, false);

或jQuery:

$(window).click(function (e) {
    if ($('#box')[0].contains(e.target)) {
        alert('Box clicked!');
    } else {
        alert('Not box clicked!');
    }
});