Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Closing dropdown by clicking outside in Javascript (tutorial clarification)

I have attempted to implement the method of opening and closing a drop-down using Javascript via this tutorial on w3schools.com. While the function to "show" the drop-down works, the one to close it does not. Furthermore, there is no explanation alongside this code to explain why it should work, making it difficult to debug.

/* When the user clicks on the button, 
toggle between hiding and showing the dropdown content */
function myFunction() {
    document.getElementById("myDropdown").classList.toggle("show");
}

// Close the dropdown menu if the user clicks outside of it
window.onclick = function(event) {
  if (!event.target.matches('.dropbtn')) {

    var dropdowns = document.getElementsByClassName("dropdown-content");
    var i;
    for (i = 0; i < dropdowns.length; i++) {
      var openDropdown = dropdowns[i];
      if (openDropdown.classList.contains('show')) {
        openDropdown.classList.remove('show');
      }
    }
  }
}

My questions are, therefore,

1) whether the code in the tutorial should work for the purpose of closing the drop-down. (ANSWERED)

2) Could someone please clarify how/why this should work, for the sake of clarity for myself and future newbies who make come across the same tutorial and issue? (UNANSWERED)

Edit (MY ATTEMPT):

HTML:

<div class="sharedown">     
    <p onclick="shareVis()" class="sharebtn">&nbsp Share</p>
    <div id="mySharedown" class="sharedown-content">
        <a href="#">Self</a>
        <p>User</p><input type="text" name="user-name" placeholder="Share to">
        <a href="#">Community</a>
    </div> 
</div>

JS:

function shareVis() {
    document.getElementById("mySharedown").className = "show";
}

window.onclick = function(event) {
    if (!event.target.matches('sharebtn')) {

        var sharedowns = document.getElementsByClassName("sharedown-content");
        var i;
        for (i = 0; i < sharedowns.length; i++) {
            var openSharedown = sharedowns[i];
            if (openSharedown.classList.contains('show')) {
                openSharedown.classList.remove('show');
            }
        }
    }   
}

CSS:

/* Share dropdown menu */

p.sharebtn {

    color: darkgrey;
    font-family:calibri;
    padding: 0px;
    margin: 0px;
    font-size: 12;
    border: none;
    cursor: pointer;
    display:    inline; 
}

/* Dropdown button on hover & focus */
p.sharebtn:hover, p.sharebtn:focus {
    color: grey;

}

/* The container <div> - needed to position the dropdown content */

.sharedown {
    position: relative;
    display:    inline-block;   

}

/* Dropdown Content (Hidden by Default) */
.sharedown-content {
    display: none;
    position: absolute;
    background-color:   #f1f1f1;
    min-width:  100px;
    box-shadow: 0 2px 4px 1px #C4E3F5;
    z-index:1; /* place dropdown infront of everything else*/
}

.sharedown-content a { 
color: black;
padding: 5px 5px;
text-decoration: none;
display: block;
}

/* Show the dropdown menu (use JS to add this class to the .dropdown-
content container when the user clicks on the dropdown button) */

.show {display: block;
    position: absolute;
    background-color:   #f1f1f1;
    min-width:  100px;
    box-shadow: 0 2px 4px 1px #C4E3F5;
    opacity: 1;
    z-index:1;}
like image 614
salamander Avatar asked May 22 '18 10:05

salamander


People also ask

How do you close a drop down when clicking outside?

You can use the jQuery click() method in combination with the on() method to hide the dropdown menu when the user click outside of the trigger element.

How do you prevent the dropdown from closing by clicking outside in Javascript?

For Bootstrap 4, look for the clickEvent , and when found in the hide event, prevent the default close behavior. This dropdown will only close when the button is clicked. In some cases, you may want the Dropdown to close when the button or menu is clicked. In this case you can examine the clickEvent target.

How do you code a drop down menu in Javascript?

Use any element to open the dropdown menu, e.g. a <button>, <a> or <p> element. Use a container element (like <div>) to create the dropdown menu and add the dropdown links inside it. Wrap a <div> element around the button and the <div> to position the dropdown menu correctly with CSS.

Which tag is used for drop down list in Javascript?

The <select> element is most often used in a form, to collect user input. The name attribute is needed to reference the form data after the form is submitted (if you omit the name attribute, no data from the drop-down list will be submitted). The id attribute is needed to associate the drop-down list with a label.


1 Answers

The issue lies in shareVis function. Here

document.getElementById("mySharedown").className = "show";

you are replacing #mySharedown class name to show. Then in window.onclick

var sharedowns = document.getElementsByClassName("sharedown-content");

you are not getting any sharedowns as you already replaced the class name to show.


You can either add show class into classList
document.getElementById("mySharedown").classList.add("show");

or replace the class name with sharedown-content show

document.getElementById("mySharedown").className = "sharedown-content show";

Working solution below:

function shareVis() {
    //document.getElementById("mySharedown").className = "sharedown-content show";
    document.getElementById("mySharedown").classList.add("show");
}

window.onclick = function(event) {
    if (!event.target.matches('.sharebtn')) {

        var sharedowns = document.getElementsByClassName("sharedown-content");
        var i;
        for (i = 0; i < sharedowns.length; i++) {
            var openSharedown = sharedowns[i];
            if (openSharedown.classList.contains('show')) {
                openSharedown.classList.remove('show');
            }
        }
    }
}

document.getElementById("mySharedown").addEventListener('click',function(event){
    event.stopPropagation();
});
#mySharedown{
  display: none;
  border: 1px solid black;
}

#mySharedown.show {
  display: block;
}
<div class="sharedown">     
    <p onclick="shareVis()" class="sharebtn">&nbsp Share</p>
    <div id="mySharedown" class="sharedown-content">
        <a href="#">Self</a>
        <p>User</p><input type="text" name="user-name" placeholder="Share to">
        <a href="#">Community</a>
    </div> 
</div>

Update

To prevent the second click within #mySharedown from hiding #mySharedown, you should add another click event for #mySharedown and prevent it from bubbling up, like this

document.getElementById("mySharedown").addEventListener('click',function(event){
    event.stopPropagation();
});

Updates are included in the working solution

like image 69
Thum Choon Tat Avatar answered Oct 08 '22 23:10

Thum Choon Tat