Why is my event on body called before event on specific element?

69 views Asked by At

I have this code in my project which is using Foundation 5.5.3

$(function() {
  var $carsDropdown = $("#cars-dropdown");

  // Close cars dropdown when clicking outside of it or on close button
  $("body, #cars-dropdown .btn-close").click(function(ev) {
    if ($carsDropdown.hasClass("open")) {
      console.log("Dropdown is open");
      console.log("Closing dropdown.\n");
      Foundation.libs.dropdown.close($carsDropdown);
      // ev.stopPropagation();
    }
    else {
      console.log("Dropdown is closed\n");
    }
  });
);

I am expecting this to close the div when I click on body and that works. It also works perfectly when I click on .btn-close.

But when I click on element which should open and close the dropdown using foundation code, nothing happens. Console output is this:

Dropdown is open.
Closing dropdown.

Just like when I click on .btn-close.

From this I am concluding that somehow event on body gets triggered before foundation event on button which should toggle the dropdown. My event closes the dropdown and foundation code toggles it open.

How is it possible that body event is not triggered last? Aren't events supposed to bubble from inner most element to body tag last?

Now when I uncomment the ev.stopPropagation() line, everything works as expected. Click on body prevents propagation to some other element? How is this possible?

For testing please using this codepen: https://codepen.io/anon/pen/BZyRLp

1

There are 1 answers

2
charlietfl On

Their event listener is most likely delegated to document so you can add such functionality dynamically.

That is why you see the body event before class is added

Check the target and don't do anything if it is a data-dropdown element

$("body, #cars-dropdown .btn-close").click(function(e) {

  if (!$(e.target).closest('[data-dropdown]').length) {

    if ($carsDropdown.hasClass("open")) {
      console.log("Dropdown is open");
      console.log("Closing dropdown.\n");
      Foundation.libs.dropdown.close($carsDropdown);
    } else {
      console.log("Dropdown is closed\n");
    }
  } else {
    console.log('Foundation Dropdown button');
  }
});