Home > Software design >  close modal by clicking anywhere on the screen, not only the button
close modal by clicking anywhere on the screen, not only the button

Time:09-22

I have a piece of code which makes it possible to open a modal by clicking on a button and to close it again by clicking on the same button. I would like it to be possible to close the modal by clicking anywhere on the screen, so not just this button.

I found a lot of pieces of code online on how to do this, but since I am a beginner with JavaScript it is very hard for me to incorporate new pieces of code within my own and make it work. Can someone help me solve this, and explain my how I and where I need to add/change lines in my existing code?

Here is the link to see how the modal works right now (button top right of the screen): https://carbonrollercoaster.bsqd.me/

JavaScript

const bf = document.querySelector('#botsquad-frame');

let el = document.createElement('div');

el.setAttribute('id', 'mijnKnopje');

const inhoud = `
<div class="info-content">
  <p1>INFORMATIE: <br>            
By participating within this chat, you accept that some of the answers you give will be displayed on one of the screens within the installation.
<br><br>
HOW TO:<br>
Go in conversation with Nostos and Algia, ask them questions and discuss multiple topics. </p1> 
</div>
<div class="info-section">
  <a role="button" class="knopje info-button" style="background-color:mediumpurple">
    <div class="info-label">!</div>
  </a>
</div>
`;

el.innerHTML = inhoud;

bf.appendChild( el );

const mijnKnopje = document.querySelector('.knopje');
const mijnInfo = document.querySelector('.info-content');

mijnKnopje.addEventListener('click', () => {
  //mijnInfo.style.display = 'block';
  //mijnKnopje.style.backgroundColor = 'fuchsia';
  mijnKnopje.classList.toggle( 'active' );
  mijnInfo.classList.toggle( 'active' );
  
  let inputField = document.querySelector('.chat-input');
  if ( mijnInfo.classList.contains( 'active' ) ) {
    inputField.style.display = 'none';
  } else {
    inputField.style.display = 'revert';
  }
} );

CodePudding user response:

You could add another event listener for the whole div-info-content aka const mijnInfo and remove the active class when clicked:

const mijnInfo = document.querySelector('.info-content');

mijnInfo.addEventListener('click', () => {
  mijnKnopje.classList.remove( 'active' );
  mijnInfo.classList.remove( 'active' );
  document.querySelector('.chat-input').style.display = 'revert';
});

CodePudding user response:

Try using event delegation.

Here's a minimal reproducable example to work with.

document.addEventListener(`click`, handle);

function createOrDestroyPopupDummy(create) {
  const inhoud = `
    <div id="popup">
      <h3>INFORMATIE</h3>            
      <div>
        Als je in deze chat meedoet, kunnen antwoorden die je 
        geeft door anderen worden gezien
      </div>
      <h3>HOW TO</h3>            
      <div>
        Vraag Nostos and Algia van alles of discussieer met ze 
        over wat dan ook.
      </div>
      <div>
        <button id="closeInfo">Gezien!</div>
      </div>
    </div>`;
   const popupOpen = document.querySelector(`#popup`);
   const createBox = () => document.body.insertAdjacentHTML(`beforeend`, inhoud);
   const destroyBox = () => popupOpen && popupOpen.remove();
   return create ? createBox() : destroyBox();
}

function handle(evt) {
    // show 'popup'
    if (evt.target.id === "info") {
      return createOrDestroyPopupDummy(true);
    }
    
    // do nothing if within the box and not clicked button#closeInfo
    if (evt.target.id !== `closeInfo` && evt.target.closest(`#popup`)) {
      return;
    }
    
    // otherwise destroy the 'popup'
    return createOrDestroyPopupDummy();
}
#closeInfo {margin-top: 0.5rem;}
#popup {
  border: 2px solid green;
  box-shadow: 2px 2px 8px #999;
  width: 75vw;
  padding: 0.4rem;
  position: absolute;
  top: 50%; right: 50%;
  transform: translate(50%,-50%);
}
#popup h3 {
  margin-top: 0.2rem;
  margin-bottom: 0.1rem;
}
<button id="info">Info</button>

  • Related