JavaScript中的stopImmediatePropagation在事件处理程序中无效

4

我想使用stopImmediatePropagation来阻止同一元素上的第二个(mousedown)事件处理程序触发,但它不起作用。代码示例:

$(function() {
  var showEventsMessage = function(options) {
    options = $.extend({
      eventType: 'CLICK',
      eventTarget: this,
      suffix: '<br>'
    }, options);
    var message = options.eventType + ': ' +
      (options.eventTarget.nodeName || 'unknown') +
      options.suffix;
    $('#Messages').append(message);
  }

  $('.clickable').click(function() {
    showEventsMessage.call(this, {
      eventType: event.type
    });
  }).dblclick(function() {
    showEventsMessage.call(this, {
      eventType: event.type
    });
  }).mousedown(function() {
    showEventsMessage.call(this, {
      eventType: event.type
    });
    event.stopImmediatePropagation();
    event.preventDefault();
  }).mousedown(function() {
    showEventsMessage.call(this, {
      eventType: event.type,
      suffix: '#2<br>'
    });
  });
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='clickable'>CLICK HERE ...
  <p class='clickable'>or here!</p>
</div>
<div id="Messages"></div>

然而,如果我在调用stopImmediatePropagation的事件处理程序中添加一个event参数(请参见代码中带有“ARGUMENT ADDED HERE”的行),它确实可以正常工作!由于event是一个全局对象,这是如何可能的?我不明白到底发生了什么变化...!? 代码示例:

$(function() {
  var showEventsMessage = function(options) {
    options = $.extend({
      eventType: 'CLICK',
      eventTarget: this,
      suffix: '<br>'
    }, options);
    var message = options.eventType + ': ' +
      (options.eventTarget.nodeName || 'unknown') +
      options.suffix;
    $('#Messages').append(message);
  }

  $('.clickable').click(function() {
    showEventsMessage.call(this, {
      eventType: event.type
    });
  }).dblclick(function() {
    showEventsMessage.call(this, {
      eventType: event.type
    });
  }).mousedown(function(event) /* ARGUMENT ADDED HERE */ {
    showEventsMessage.call(this, {
      eventType: event.type
    });
    event.stopImmediatePropagation();
    event.preventDefault();
  }).mousedown(function() {
    showEventsMessage.call(this, {
      eventType: event.type,
      suffix: '#2<br>'
    });
  });
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='clickable'>CLICK HERE ...
  <p class='clickable'>or here!</p>
</div>
<div id="Messages"></div>


火狐浏览器没有定义window.event。你使用的是哪个浏览器? - Axel F
Chrome、Opera、Edge 和 IE 在事件监听器执行时都会定义 window.event。 - Marko
3个回答

3

区别在于参数是jQuery事件对象,没有参数时使用原始JS事件对象。您获得jQuery版本是因为您使用jQuery初始化事件处理程序。

您尝试调用的函数“stopImmediatePropagation”是一个jQuery函数,在原始JS事件中未定义,这就是为什么它无法工作的原因。


1
^ 这不是真的! https://developer.mozilla.org/zh-CN/docs/Web/API/Event/stopImmediatePropagation - Andrew

-1

实际上,stopImmediatePropagation是一个jQuery方法。 通过在mousedown事件回调中传递event参数,它会传递jQuery引用,然后使用它调用stopImmediatePropagation,这样就可以正常工作。但是,如果您不传递event参数,则它将指向默认的JavaScript事件对象,该对象没有stopImmediatePropagation的引用。因此,在那里它不起作用。
请参见:事件处理函数内部


-1
请注意,您在两种情况下都添加了jQuery事件处理程序
在第一种情况下,您试图通过在全局(本地JS)事件上调用stopImmediatePropagation来阻止执行jQuery处理程序。因此,它不起作用。
当您从参数中提取event时,您正在调用jQuery.Event上的stopImmediatePropagation。因此,成功停止了执行jQuery处理程序。

1
抱歉,这只是对@Joost_96答案的重新表述。由于他先发布了,因此应该给予他相应的荣誉。 - Tarun Lalwani
1
很好,@TarunLalwani。当我打开这个问题时,没有答案,所以我发了这个回答。 - yeshashah
有时会发生这种情况,您应该确保在发布答案之前刷新页面。这有助于避免这种情况的发生。 - Tarun Lalwani
好的,下次会注意的。 - yeshashah

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接