Marko
Marko

Reputation: 1592

JavaScript stopImmediatePropagation not working in event handler

I want to use stopImmediatePropagation to prevent a second (mousedown) hadler on the same element to fire, but it doesn't work. Code sample:

$(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>

However, if I add an event argument to the event handler that calls stopImmediatePropagation (in code see line with "ARGUMENT ADDED HERE"), it does work! Since event is a global object, how is this possible, I don't understand what effectively changes...!? Code example:

$(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>

Upvotes: 4

Views: 2230

Answers (3)

Praveen Poonia
Praveen Poonia

Reputation: 765

Actully stopImmediatePropagation is a jquery method. By passing event in mousedown event callback it pass jquery reference and stopImmediatePropagation is then called with it and works, But when you do not pass event param, it points to the default javascript event object, which do not have reference of stopImmediatePropagation. So, it doen't work there
See: Inside the Event Handling Function

Upvotes: -1

yeshashah
yeshashah

Reputation: 1554

Notice that you have added jQuery event handlers in both cases.

In first case, you are trying to stop a jQuery handler from being executed by calling stopImmediatePropagation on a global (native JS) event. Hence, it does not work.

When you extract event from arguments, you are calling stopImmediatePropagation on jQuery.Event. Hence, it is successful in stopping execution of jQuery handler.

Upvotes: -1

Joost K
Joost K

Reputation: 1116

The difference is that the parameter is a jQuery event object and without the parameter it uses the original JS event object. You get the jQuery version because you initialize the event handler with jQuery.

The function that you're trying to call "stopImmediatePropagation" is a jQuery function and is not defined in the original JS event, and that is why it won't work.

Upvotes: 3

Related Questions