skip to Main Content

I would like the modal box to close if you click outside of .modal but not if you click on the prev or next links, I am having trouble with that last part. I am not sure how to prevent the modal from closing if the prev or next links are clicked. The next buttons will be scrolling through different boxes so I need them clickable. Any help is appreciated.

window.addEventListener('load', setup);

const get = document.getElementById.bind(document);
const query = document.querySelector.bind(document);

function setup() {
  
  let modalRoot = get('modal-root');
  let button = get('modal-opener');
  let modal = query('.modal');
  
  modalRoot.addEventListener('click', rootClick);
  button.addEventListener('click', openModal);
  modal.addEventListener('click', modalClick);
  
  function rootClick() {
    modalRoot.classList.remove('visible');
  }
  
  function openModal() {
    modalRoot.classList.add('visible');
  }
  
  function modalClick(e) {
    e.preventDefault();
    e.stopPropagation();
    e.stopImmediatePropagation();
    return false;
  }
  
}
#modal-root {
  position: fixed;
  overflow: hidden;
  background-color: rgba(0, 0, 0, 0.4);
  left : 0;
  top: 0;
  width: 0px;
  height : 0px;
  opacity: 0;
  transition: opacity 0.15s ease-out, width 0s linear 0.15s, height 0s linear 0.15s;
}

#modal-root.visible {
  width: 100%;
  height: 100%;
  opacity: 1;
  transition: opacity 0.15s ease-out;
}

.modal {
  margin: 0 auto;
  width: 40%;
  background-color: white;
  padding: 20px;
  border-radius: 5px;
  position: relative;
  top: 50%;
  transform: translateY(-50%);
}
.prevslide, .nextslide{
    cursor: pointer;
    position: absolute;
    top: 50%;
    width: auto;
    padding: 16px;
    margin-top: -50px;
    color: red;
    font-weight: 700;
    font-size: 20px;
    transition: .6s ease;
    border-radius: 0 3px 3px 0;
    user-select: none;
    -webkit-user-select: none;
}

.nextslide {
  right: 0px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="root">
  <button id="modal-opener">Open Modal</button>
</div>
<div id="modal-root">
  <div class="modal">
    <h3>Modal Header</h3>
    <p>Modal contentt</p>
  </div>
<a class="prevslide" >Previous</a><a class="nextslide">Next</a>
</div>

2

Answers


  1. You could stop the event propagation when the prev/next buttons are clicked.

    window.addEventListener('load', setup);
    
    const get = document.getElementById.bind(document);
    const query = document.querySelector.bind(document);
    
    function setup() {
      
      let modalRoot = get('modal-root');
      let button = get('modal-opener');
      let modal = query('.modal');
      
      modalRoot.addEventListener('click', rootClick);
      button.addEventListener('click', openModal);
      modal.addEventListener('click', modalClick);
    
      let prevBtn = modalRoot.querySelector(".prevslide");
      let nextBtn = modalRoot.querySelector(".nextslide");
      prevBtn.addEventListener("click", e => e.stopPropagation());
      nextBtn.addEventListener("click", e => e.stopPropagation());
      
      function rootClick() {
        modalRoot.classList.remove('visible');
      }
      
      function openModal() {
        modalRoot.classList.add('visible');
      }
      
      function modalClick(e) {
        e.preventDefault();
        e.stopPropagation();
        e.stopImmediatePropagation();
        return false;
      }
      
    }
    #modal-root {
      position: fixed;
      overflow: hidden;
      background-color: rgba(0, 0, 0, 0.4);
      left : 0;
      top: 0;
      width: 0px;
      height : 0px;
      opacity: 0;
      transition: opacity 0.15s ease-out, width 0s linear 0.15s, height 0s linear 0.15s;
    }
    
    #modal-root.visible {
      width: 100%;
      height: 100%;
      opacity: 1;
      transition: opacity 0.15s ease-out;
    }
    
    .modal {
      margin: 0 auto;
      width: 40%;
      background-color: white;
      padding: 20px;
      border-radius: 5px;
      position: relative;
      top: 50%;
      transform: translateY(-50%);
    }
    .prevslide, .nextslide{
        cursor: pointer;
        position: absolute;
        top: 50%;
        width: auto;
        padding: 16px;
        margin-top: -50px;
        color: red;
        font-weight: 700;
        font-size: 20px;
        transition: .6s ease;
        border-radius: 0 3px 3px 0;
        user-select: none;
        -webkit-user-select: none;
    }
    
    .nextslide {
      right: 0px;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div id="root">
      <button id="modal-opener">Open Modal</button>
    </div>
    <div id="modal-root">
      <div class="modal">
        <h3>Modal Header</h3>
        <p>Modal contentt</p>
      </div>
    <a class="prevslide" >Previous</a><a class="nextslide">Next</a>
    </div>
    Login or Signup to reply.
  2. Just define the both buttons and change your rootClick() function to check if the clicked target isn’t one of the both buttons,

    Check the snippet

    window.addEventListener('load', setup);
    
    const get = document.getElementById.bind(document);
    const query = document.querySelector.bind(document);
    
    function setup() {
      
      let modalRoot = get('modal-root');
      let button = get('modal-opener');
      let modal = query('.modal');
      // Define the both buttons
      let prev = query('.prevslide')
      let next = query('.nextslide')
      
      modalRoot.addEventListener('click', rootClick);
      button.addEventListener('click', openModal);
      modal.addEventListener('click', modalClick);
      
      function rootClick(e) {
      // Create if statement to check the target
      if(e.target != prev && e.target != next)
        modalRoot.classList.remove('visible');
      }
      
      function openModal() {
        modalRoot.classList.add('visible');
      }
      
      function modalClick(e) {
        e.preventDefault();
        e.stopPropagation();
        e.stopImmediatePropagation();
        return false;
      }
      
    }
    #modal-root {
      position: fixed;
      overflow: hidden;
      background-color: rgba(0, 0, 0, 0.4);
      left : 0;
      top: 0;
      width: 0px;
      height : 0px;
      opacity: 0;
      transition: opacity 0.15s ease-out, width 0s linear 0.15s, height 0s linear 0.15s;
    }
    
    #modal-root.visible {
      width: 100%;
      height: 100%;
      opacity: 1;
      transition: opacity 0.15s ease-out;
    }
    
    .modal {
      margin: 0 auto;
      width: 40%;
      background-color: white;
      padding: 20px;
      border-radius: 5px;
      position: relative;
      top: 50%;
      transform: translateY(-50%);
    }
    .prevslide, .nextslide{
        cursor: pointer;
        position: absolute;
        top: 50%;
        width: auto;
        padding: 16px;
        margin-top: -50px;
        color: red;
        font-weight: 700;
        font-size: 20px;
        transition: .6s ease;
        border-radius: 0 3px 3px 0;
        user-select: none;
        -webkit-user-select: none;
    }
    
    .nextslide {
      right: 0px;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div id="root">
      <button id="modal-opener">Open Modal</button>
    </div>
    <div id="modal-root">
      <div class="modal">
        <h3>Modal Header</h3>
        <p>Modal contentt</p>
      </div>
    <a class="prevslide" >Previous</a><a class="nextslide">Next</a>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search