Why is my modal close button not working?

I "made" a modal (got it from here). However, the button to close the modal just doesn't work. The event to click on any part the modal to close it does work though. I've spent hours on this and researched as much as I could but I just can't seem to find the issue.

const modal = document.querySelector(".modal");
const closeModal = document.querySelector(".closeModal");

document.querySelector("#shortCircuit").onclick = function() {
  modal.setAttribute('style', 'display: block;');
}

closeModal.onclick = function() {
  modal.setAttribute('style', 'display: none;');
}

window.onclick = function(event) {
  if (event.target === modal) {
    modal.setAttribute('style', 'display: none;');
  }
}
.modal {
  display: none;
  position: fixed;
  z-index: 1;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  overflow: auto;
  background-color: hsl(0, 0%, 0%);
  background-color: hsla(0, 0%, 0%, 0.4);
}

.modal-content {
  background-color: hsl(0, 0%, 100%);
  margin: 15% auto;
  padding: 20px;
  border: 1px solid #878787;
  width: 80%;
}

.closeModal {
  color: #aaa;
  float: right;
  font-size: 2em;
  font-weight: bold;
}

.closeModal:hover,
.closeModal:focus {
  color: black;
  text-decoration: none;
  cursor: pointer;
}
<div class="flexLayout">
  <div id="shortCircuit">
    <h1>Short-circuit</h1>
    <div class="modal">
      <div class="modal-content">
        <button class="closeModal">&times;</button>
      </div>
    </div>
  </div>
</div>

2 answers

  • answered 2018-12-05 20:09 j08691

    The problem is that your click on the X bubbles up the DOM and triggers the open modal code again on <div id="shortCircuit">. You can stop that with e.stopPropagation();

    const modal = document.querySelector(".modal");
    const closeModal = document.querySelector(".closeModal");
    
    document.querySelector("#shortCircuit").onclick = function() {
      modal.setAttribute('style', 'display: block;');
    }
    
    closeModal.onclick = function(e) {
      e.stopPropagation();
      modal.setAttribute('style', 'display: none;');
    }
    
    window.onclick = function(event) {
      if (event.target === modal) {
        modal.setAttribute('style', 'display: none;');
      }
    }
    .modal {
      display: none;
      position: fixed;
      z-index: 1;
      left: 0;
      top: 0;
      width: 100%;
      height: 100%;
      overflow: auto;
      background-color: hsl(0, 0%, 0%);
      background-color: hsla(0, 0%, 0%, 0.4);
    }
    
    .modal-content {
      background-color: hsl(0, 0%, 100%);
      margin: 15% auto;
      padding: 20px;
      border: 1px solid #878787;
      width: 80%;
    }
    
    .closeModal {
      color: #aaa;
      float: right;
      font-size: 2em;
      font-weight: bold;
    }
    
    .closeModal:hover,
    .closeModal:focus {
      color: black;
      text-decoration: none;
      cursor: pointer;
    }
    <div class="flexLayout">
      <div id="shortCircuit">
        <h1>Short-circuit</h1>
        <div class="modal">
          <div class="modal-content">
            <button class="closeModal">&times;</button>
          </div>
        </div>
      </div>
    </div>

  • answered 2018-12-05 20:18 Avi Areman

    The problem with the code is that it is closing the dialogue and then triggering the show dialog event. This is because the click event bubbles through every layer underneath the mouse. To stop this just change the code to this

    closeModal.onclick = function(e) {
      modal.setAttribute('style', 'display: none;');
        e.preventDefault();
        e.stopPropagation();
    }