1

I'm looking to understand how to hide an element when you click outside.

Here's one from:

https://css-tricks.com/dangers-stopping-event-propagation/

$(document).on('click', function(event) {
  if (!$(event.target).closest('#menucontainer').length) {
    // Hide the menus.
  }
});

Could someone break this down for me please? I don't understand why we need to use the length property?

Also does closest traverse up to the top of the DOM from wherever it starts and then stop one it reaches the top?

Cheers

Joe Consterdine
  • 1,035
  • 1
  • 18
  • 37
  • What this does is as follows: First: check that there is no `#menucontainer` that exist (the `.length`-check) as `.closest`. Hence, if you click within the popup, the check will traverse up, and find `#menucontainer` - if you click outside it, there will be no such container, and it will close. – junkfoodjunkie Oct 31 '16 at 16:11
  • `closest('#menucontainer')` is the same as `$('#menucontainer')` as we already mentioned - if not then the html is invalid since IDs need to be unique – mplungjan Oct 31 '16 at 16:13
  • i'm not totatally agree closest refers to event.target fires most nearly element ... ( if they are more than one ) – Joaquin Javi Oct 31 '16 at 16:16
  • So the test is if the event took place inside the container? Why not add the click to the container and test if the event target was something you wanted to click? – mplungjan Oct 31 '16 at 16:31
  • Cheers guys so am I right in thinking .length is checking for true or false? – Joe Consterdine Oct 31 '16 at 16:32

3 Answers3

2

You need to check the length because jQuery queries always return a result, which is empty if nothing was found. Once you check the length you can tell if the click is inside (length > 0, an element was found) or outside (length === 0, no element was found)

Meir
  • 14,081
  • 4
  • 39
  • 47
1

Here is a break down:

line 1: $(document).on('click', function(event) { ... });

binds on any click made in your document (DOM). make use that you unbind (.off('click', .....); after you used it. Otherwise it will be endlessly executing on every click.

line 2:

if (!$(event.target).closest('#menucontainer').length) {

event.target ===(equals) the element that is click in the dom.

.closest('#menucontainer') = get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree. Meaning: when there is clicked inside MenuContainer it will return an array with the first '#menucontainer' element. When there is click outside the MenuContainer it will return an Empty array. (no element found).

.length = The default behavior from JQuery is to return an empty array when nothing is found. If you put and empty array in a If statement it will return true. because its an Defined Object. Its defined as an Array. however the number 0 == false. thats with they put .length on the array. It will return 0 (false) when its empty of > 0 (true) when it found an element.

In JavaScript, everything is 'truthy' or 'falsy', and for numbers 0 (and NaN) means false, everything else true.

check NickG his link( Is there an "exists" function for jQuery? )

Community
  • 1
  • 1
0

A jQuery selector will return an array with all the matched elements. If you use an ID as selector such as ('#menucontainer') the length will be 0 or 1. The closest menu will not be found, if we click something outside of the menu, the negation will be true and menu can be hidden.

 // Get the current clicked element
!$(event.target)
// Get closest container with this id, bubbling up the DOM
.closest('#menucontainer')
// returns 1 if we clicked something inside the menu and 0 if we clicked something outsite
.length
oshell
  • 8,923
  • 1
  • 29
  • 47