Alexander Solonik
Alexander Solonik

Reputation: 10230

hide vs hidden event in dropdown.js

I am a JS developer studying events and I need some help from you people. I have a very straight forward question. While going through the code of dropdown.js, I came across the following lines of JS :

$parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget));

if (e.isDefaultPrevented()) return;

$this.attr('aria-expanded', 'false');
$parent.removeClass('open').trigger('hidden.bs.dropdown', relatedTarget);

I noticed how the event 'hide' is triggered before 'hidden'.

Now, the bootstrap documentation expalin these events as such:

hide.bs.dropdown :: This event is fired immediately when the hide instance method has been called.

hidden.bs.dropdown This event is fired when the dropdown has finished being hidden from the user (will wait for CSS transitions, to complete).

Notice how the documentation says hidden is fired only after the dropdown is being finished hidden from the user. My question is: is it the placement of code that is causing hide to fire first and hidden to fire second?

the lines of code can be found here too.

EDIT:: :: i mean if i were to place hidden event before hide, would the bootstrap documentation still be right ?

Upvotes: 1

Views: 540

Answers (2)

wahwahwah
wahwahwah

Reputation: 3177

The short answer to your question is no - the placement/order of the code does not not ensure that hide-hidden are "fired" in that order. It is entirely possible to delay the execution of all or part of hide.bs.dropdown() until after hidden.bs.dropdown() has fired.

Browsers have an inner loop called an event loop that processes queued events/functions/etc. The "the placement of code" in your example merely shows the order in which those functions/events are added to this queue.

Here's an example of pushing a function to the end of the queue using setTimeout():

// the timeout delay is 0, but it still moves the 'delayEvent' to the end of the queue:
$(document).on("delayEvent", {
  foo: "bar"
}, function(event) {
  setTimeout(function() {
    console.log(event.data.foo);
  }, 0);
});


$(document).on("fifoEvent", {
  bim: "baz"
}, function(event) {
  console.log(event.data.bim);
});


$(document).trigger("delayEvent"); // bar
$(document).trigger("fifoEvent"); // baz
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

Upvotes: 1

Charbz
Charbz

Reputation: 536

If you look at what is happening in between the first event and the second event, you will see this

 $this.attr('aria-expanded', 'false');
 $parent.removeClass('open') // and then .trigger('hidden.bs.dropdown', relatedTarget);

so the two lines mentioned above are responsible for the actual hiding of the element. This means, as long as hide.bs.dropdown is placed before those two lines, and hidden.bs.dropdown is placed after them , then the documentation will be right

Upvotes: 2

Related Questions