如何添加一个事件处理程序,可以阻止使用jQuery的另一个单击事件处理程序?

时间:2015-02-25 12:50:54

标签: javascript jquery javascript-events

我想为链接或按钮实现一个确认逻辑,我可以使用特殊的data-confirm属性来注释相关元素。如果元素上存在此属性,我想附加一个单击处理程序,它可以阻止任何其他处理程序,包括默认事件,以及在添加确认处理程序之前或之后添加的其他jQuery处理程序。

这是我的代码:

  $(document).on("click", "a[data-confirm], button[data-confirm]", function(e) {
    var confirmData = $(this).data("confirm");
    if (confirmData === "true")
      confirmData = $(this).prop("title");
    if (confirmData && !confirm(confirmData)) {
      e.stopImmediatePropagation();
      e.stopPropagation();
      e.preventDefault();
      return false;
    }
    return true;
  });

问题是我不确定这个处理程序将进入处理程序列表的位置,所以我猜其他处理程序很可能在它之前执行。另外,我不确定此处理程序是否会以knockoutjs'点击绑定为例。

2 个答案:

答案 0 :(得分:1)

要防止其他处理程序被调用,请使用stopImmediatePropagation()并使用preventDefault()防止默认行为。

像这样:

$("body").on("click", ".elementClass[attributeName]", function(event){
    event.stopImmediatePropagation();
    event.preventDefault();
});

通过在选择器中添加[attributeName],选择器将仅应用于具有属性“attributeName”的元素

在上面的示例中,这将在$(document)处理程序之前执行,因为事件会使DOM冒泡并在到达body之前到达document。为了确保更快地附加此事件,您可以将处理程序附加到元素,如下所示:

$(".elementClass[attributeName]").on("click", function(event){
    event.stopImmediatePropagation();
    event.preventDefault();
});

这样做的缺点是,必须在元素具有属性后附加此处理程序。

然而,只有vanilla JavaScript可以使用的另一种技术是事件捕获:https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener

  

如果为true,则useCapture表示用户希望启动捕获。启动捕获后,指定类型的所有事件将被分派到已注册的侦听器,然后再分派到DOM树中它下面的任何EventTarget。向上冒泡到树中的事件不会触发指定使用捕获的侦听器

您可以这样做:

document.addEventListener("click", function(event){
    if(event.target.hasAttribute("attributeName")){ // jQuery: if($(event.target).attr("attributeName")){...
        event.stopPropagation();
        event.preventDefault();
        //Do stuff
    }
}, true);

通过在结尾处添加true来捕获事件,这意味着它将在其他处理程序之前运行。

答案 1 :(得分:0)

如果元素具有多个单击处理程序,则不指定这些处理程序的执行顺序。所以你不能可靠地让人永远先执行。

  

虽然EventTarget上的所有EventListener都保证由EventTarget接收的任何事件触发,但是没有规定它们将接收与EventTarget上的其他EventListener相关的事件的顺序。 / p>

W3C-Events-flow-basics