Sergi Khizanishvili
Sergi Khizanishvili

Reputation: 587

Can't find out why javascript code does not work

I have two JS codes on my page:

Small Dropdown menu which uses this script:

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');
      }
    }
  }
}

and a modal box (popup window that is displayed on top page) which uses next script:

var modal = document.getElementById('myModal');
var btn = document.getElementById("myBtn");
var span = document.getElementsByClassName("close")[0];
btn.onclick = function() {
    modal.style.display = "block";
}
span.onclick = function() {
    modal.style.display = "none";
}
window.onclick = function(event) {
    if (event.target == modal) {
        modal.style.display = "none";
    }
}

Problem:

Everything is working perfectly except one thing: In the first code where script is used for the Dropdown menu there is code which is used to close menu when you click outside of it. But when I'm using both scripts on one page above mentioned thing does not work. (To be clear: When I use Dropdown JS on another page where I don't have second script, everything works perfect).

Can you help find out what may cause the problem?

Upvotes: 0

Views: 125

Answers (4)

Hopeful Llama
Hopeful Llama

Reputation: 758

In your second block of code, you are overwriting the onclick handler for the window.

You'll need to modify the handler to handle both functions, rather than overwriting it.

For example:

window.onclick = function(event) {
    // Taken from the first code block; Handles the closing of the dropdown
    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');
        }
    }

    // Taken from the second code block
    if (event.target == modal) {
        modal.style.display = "none";
    }
}

Upvotes: 4

koffeinfrei
koffeinfrei

Reputation: 2045

The second script assigns a new callback to window.onclick, which overwrites the one from the first script.

You could use addEventListener to add a second listener.

Upvotes: 2

metal03326
metal03326

Reputation: 1263

Use document.body.addEventListener('click') instead of window.onclick. Like so:

function myFunction() {
    document.getElementById("myDropdown").classList.toggle("show");
}
// Close the dropdown menu if the user clicks outside of it
document.body.addEventListener('click', 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');
      }
    }
  }
});

and

var modal = document.getElementById('myModal');
var btn = document.getElementById("myBtn");
var span = document.getElementsByClassName("close")[0];
btn.onclick = function() {
    modal.style.display = "block";
}
span.onclick = function() {
    modal.style.display = "none";
}
document.body.addEventListener('click', function(event) {
    if (event.target == modal) {
        modal.style.display = "none";
    }
});

Upvotes: 3

Mchl
Mchl

Reputation: 62359

That's beacuse both scripts attach a function to window.onclick. When you use both at the same time, to one that does this last wins. Use addEventListener instead: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener

Upvotes: 1

Related Questions