-2

I was writing code for closing dropdown window outside of its scope. For that purpose I used simple if condition to check, whether click event's id coincides with the id of dropdown button not every click should be considered to close menu). It was unexpected to see, that almost same condition statements are considered differently by vanilla JS.

To show the difference, I'll provide here two code snippets:

// Close the dropdown menu if the user clicks outside of it
window.onclick = function(event){
    if (event.target.id == dropDownBtn.id){
        console.log("ok"); //  console output: ok
    }
}
// Close the dropdown menu if the user clicks outside of it
window.onclick = function(event) {
    if (event.target.matches(dropDownBtn.id)){
        console.log("ok"); //  console output:
    }
}

Having zero to little experience in JS, I'd like to know why first snippet works well, whereas second not.

bkh6722
  • 133
  • 3
  • 11
  • 2
    _"This question doesn't show any research effort"_ is a downvote reason. Reading the [documentation](https://developer.mozilla.org/en-US/docs/Web/API/Element/matches) is the first step. [How much research effort is expected of Stack Overflow users?](https://meta.stackoverflow.com/questions/261592/how-much-research-effort-is-expected-of-stack-overflow-users) _"Asking a question on Stack Overflow should be the last step in your process for finding an answer"_ – jabaa Jun 20 '23 at 10:48
  • then im wondering why u guys not downvoting this kind of questions? https://stackoverflow.com/questions/359494/which-equals-operator-vs-should-be-used-in-javascript-comparisons?rq=1 – bkh6722 Jun 20 '23 at 10:49
  • 1
    That question is from 2008. The downvote reasons have probably changed in the last 15 years. – jabaa Jun 20 '23 at 10:53
  • simply said community was less toxic. – bkh6722 Jun 20 '23 at 10:54
  • No, it's written in the tooltip on the downvote button. It's not the community. It's the platform. I can't change the tooltips on this platform. – jabaa Jun 20 '23 at 10:55

3 Answers3

1

event.target.matches(dropDownBtn.id) is using the matches method to check if the element that was clicked (event.target) matches the CSS selector provided (dropDownBtn.id).

The matches method checks if the element itself or any of its ancestors match the selector. But, dropDownBtn.id only provides the id of the dropdown button element, which is not a valid CSS selector. Check this documentation for more info (https://developer.mozilla.org/en-US/docs/Web/API/Element/matches)

0

To fix the second code snippet, you can modify the condition to use a valid CSS selector by prefixing the id with a # symbol, like this:

window.onclick = function(event) {
    if (event.target.matches('#' + dropDownBtn.id)){
        console.log("ok"); // console output: ok
    }
}
pallab97
  • 26
  • 1
0

You have an error in the matches example. You need the '#' prefix:

// Close the dropdown menu if the user clicks outside of it
window.onclick = function(event) {
    if (event.target.matches('#' + dropDownBtn.id)){
        console.log("ok"); //  console output:
    }
}

Otherwise the 2 methods seems equal.

BUT you have a problem with your approach. e.target could be any clicked element in the dropdown.

So to solve that you need to check whether the clicked element is INSIDE your dropdown or your dropdown itself, also using document looks more idiomatic:

document.addEventListener('click', e => {
  if(e.target.closest('#' + dropDownBtn.id)){
    return;
  }
  // close your dropdown here
});

Alexander Nenashev
  • 8,775
  • 2
  • 6
  • 17
  • hmm, interesting approach with "closest". I wasnt so proficient, so i simply specified like that: ```if(!event.target.matches('#chooseModeButton') && dropDownWin.classList.contains('open') && !event.target.matches('.menu-option'))``` – bkh6722 Jun 21 '23 at 06:52