JQuery stop event from starting

I have a simple script as shown in the fiddle which is on

Initially, the event is binded

for only one button A and the click

event is triggered manually in both buttons (A and B).

The event handler for Button A now has an event handler for Button B attached to it. It is not expected to call B's callback because it is bound after the event has fired.

But the callback is still executing. Where am I going wrong?

HTML:

<div>
    <button class="a">botton A</button>
    <button class="b">button B</button>
</div>

      

JS:

$(function () {
    $('div').on('click', '.a', function (e) {
        e.preventDefault();
        $('div').on('click', '.b', function () {
            alert('Can"t see me')
        });
    });
    $('button').trigger('click');
});

      

FIDDLE LINK

EDIT:
I have this scenario in my project and now I knew why this is happening :). But how can I stop the event from propagating?

+3


source to share


4 answers


$('button').trigger('click');

fires a click event on both buttons in the order in which they appear in the markup in the document. Because the bubbling event occurs synchronously, the for event is .b

bound before the click event is triggered on that button. Here's the breakdown:

  • $('button')

    creates a collection of buttons .a

    and a button .b

    .
  • .trigger('click');

    iterates through each button in the collection and fires a click event. Button
  • .a

    receives a click event and fires the event handler you registered for it on page load.
  • The event handler for is .b

    registered in the event handler callback for .a

    . Button
  • .b

    receives a click event from .trigger('click');

    as it is second in the collection.
  • The event listener callback for the button .b

    raises a popup warning.

Since you only want to click a button .a

, click any of the following for your current document:

  • $('.a').trigger('click');

  • $('button.a').trigger('click');

    (although this is redundant)
  • $('button').get(0).trigger('click');

    (since it .a

    is the 0th indexed element of the button)

EDIT While this is unrelated to the question, you might have wanted to register the event for .b

just one time by doing the following:

$('.a').one('click', function (e) {



$(function() {
  $('.a').one('click', function(e) {
    e.preventDefault();
    $('div').on('click', '.b', function() {
      alert('Can\'t see me');
    });
  });
  $('.a').trigger('click');
});
      

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
  <button class="a">button A</button>
  <button class="b">button B</button>
</div>
      

Run codeHide result


SECOND EDIT If you want to stop the propagation of events, you need to add another event listener, for example:

$(function() {
  $('.a').one('click', function() {
    $('.b').on('click', function(e) {
      e.stopPropagation();
      alert('Can see me');
    });
    $('div').on('click', '.b', function() {
      alert('Can\'t see me');
    });
  });
  $('button').trigger('click');
});
      

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
  <button class="a">button A</button>
  <button class="b">button B</button>
</div>
      

Run codeHide result


+2


source


This is because of $('button').trigger('click');

.

This triggers a click on every button - first it clicks on .a

, which binds the click handler to .b

, then clicks on .b

.



In my experiment, just clicking a button .b

fixed this first, but I wouldn't rely on that.

+1


source


Perhaps this is because the click is triggered in all instances of buttons in sequence ...

button a

the click is fired first ... in your callback you are binding the button b

click callback ...

... then ... the button b

click is triggered ... so the callback for b is executed ...

All this happens in one call: $('button').trigger('click');

Edit: Others have probably answered this before I have it ... but iteration triggers a click on the correct element:

$('.a').trigger('click');

      

+1


source


Execution order:

  • bind.a
  • trigger start button (say a)
  • callback for: bind b
  • trigger start button (b)
  • callback for b

Even $("button").trigger("click")

- it's one line, it's kind of a loop that works as if it were:

var buttonElms = $("button");
for (var index in buttonElms) {
   buttonElms[index].trigger("click");
}

      

0


source







All Articles