skip to Main Content

I have a problem.
I have a series of popups and I am not able to make the opened one closing when opening another.
I’d like to have a result in which I open one of them and it closes when I open another.
Here’s a piece of my code:

<script>
    function popup0(){
        let popup = document.getElementById('popup0');
        popup.classList.toggle('show');
    }
</script>
<p class = 'popup' onclick = 'popup0()'>El Gringo
    <span class = 'popuptext' id = 'popup0'>
        Each time he loses a life point due to a card played by another player, Gringo draws a random card from the hand of that player (one card for each life).<br>(3 life points)
    </span>
</p><br>
<script>
                function popup1(){
        let popup = document.getElementById('popup1');
        popup.classList.toggle('show');
    }
</script>
<p class = 'popup' onclick = 'popup1()'>Willy the Kid
    <span class = 'popuptext' id = 'popup1'>
        During his turn, he can play any number of 'Bang!' cards.<br>(4 life points)
    </span>
</p><br>
<script>
    function popup2(){
        let popup = document.getElementById('popup2');
        popup.classList.toggle('show');
    }
</script>
<p class = 'popup' onclick = 'popup2()'>Lucky Duke
    <span class = 'popuptext' id = 'popup2'>
        Each time he is required to 'Draw!', he flips the top two cards from the deck and chooses the result he prefers. Both cards are discarded afterwards.<br>(4 life points)
    </span>
</p><br>
<script>
    function popup3(){
        let popup = document.getElementById('popup3');
        popup.classList.toggle('show');
    }
</script>
<p class = 'popup' onclick = 'popup3()'>Kit Carlson
    <span class = 'popuptext' id = 'popup3'>
        During Phase 1 of his turn, he looks at the top three cards of the deck, then chooses two to put into his hand and puts the remaining card back onto the deck, face down.<br>(4 life points)
    </span>
</p><br>
<script>
    function popup4(){
        let popup = document.getElementById('popup4');
        popup.classList.toggle('show');
    }
</script>

EDIT FOR epascarello:

The new code:

    <script>
    function popup(elem) {
        const toggles = document.querySelector(elem.dataset.toggles);
        const active = document.querySelector('.popuptext.show');
         if (active && active !== toggles) {
            active.classList.remove('show');
        }
         toggles.classList.toggle('show');
    }
     document.querySelectorAll('[data-toggles]').forEach(elem => {
        elem.addEventListener('click', () => popup(elem));
    });
</script>
<p class = 'popup' data-toggles = '#popup0'>Willy the Kid
    <span class = 'popuptext' id = 'popup0'>
        During his turn, he can play any number of 'Bang!' cards.<br>(4 life points)
    </span>
</p><br>
<p class = 'popup' data-toggles = '#popup1'>Suzy Lafayette
    <span class = 'popuptext' id = 'popup1'>
        Each time she has no cards in her hand, she instantly draws a card from the draw pile. This cannot be performed while she is under the effect of Duel. When the duel ends and she has no cards in her hands, she may take one card again.<br>(4 life points)
    </span>
</p><br>
<p class = 'popup' data-toggles = '#popup2'>Kit Carlson
    <span class = 'popuptext' id = 'popup2'>
        During Phase 1 of his turn, he looks at the top three cards of the deck, then chooses two to put into his hand and puts the remaining card back onto the deck, face down.<br>(4 life points)
    </span>
</p><br>
<p class = 'popup' data-toggles = '#popup3'>Jesse Jones
    <span class = 'popuptext' id = 'popup3'>
        During Phase 1 of his turn, he may choose to draw the first card from the deck, or randomly from the hand of any other player, then he draws the second card from the deck.<br>(4 life points)
    </span>
</p>

Here the CSS of popups:

    .popup{
        position: relative;
        display: inline-block;
        cursor: pointer;
        -webkit-user-select: none;
        -moz-user-select: none;
        -ms-user-select: none;
        user-select: none;
    }
    .popup .popuptext{
        visibility: hidden;
        width: 320px;
        background-color: #000;
        color: #FFF;
        text-align: center;
        border-radius: 6px;
        padding: 8px 0;
        position: absolute;
        z-index: 1;
        bottom: 125%;
        left: 50%;
        margin-left: -80%;
    }
    .popup .popuptext::after{
        content: '';
        position: absolute;
        top: 100%;
        left: 50%;
        margin-left: -10px;
        border-width: 10px;
        border-style: solid;
        border-color: #000 transparent transparent transparent;
    }
    .popup .show{
        visibility: visible;
        -webkit-animation: fadeIn 1s;
        animation: fadeIn 1s;
    }
    @-webkit-keyframes fadeIn{
        from{
            opacity: 0;
        }
        to{
            opacity: 1;
        }
    }
    @keyframes fadeIn{
        from{
            opacity: 0;
        }
        to{
            opacity: 1;
        }
    }

It asks too add details because of too much code… I have to temporarily add spam lines, ignore them:
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

2

Answers


  1. You can just create a new function to hide opened popups and call it inside each function.

    Like below:

        function hideOther(popupElem) {
      document.querySelectorAll('.popuptext:not(#'+popupElem+')').forEach(elem => {
        elem.classList.remove('show');
      });
    }
    
    function popup0() {  
      let popup = document.getElementById('popup0');
      hideOther('popup0');
      popup.classList.toggle('show');
    }
    

    You need to call hideOther inside each popup function like here we called it inside popup0

    Updated Passed current id to the function and checked to get only other popups to close

    Login or Signup to reply.
  2. Just look up the element with the active class and remove it. I changed the code to not use inline events and use data attribute to determine what to show to remove a lot of repeated code.

    function popup(elem) {
      const toggles = document.querySelector(elem.dataset.toggles);
      const active = document.querySelector('.popuptext.show');
    
      if (active && active !== toggles) {
        active.classList.remove('show');
      }
    
      toggles.classList.toggle('show');
    }
    
    document.querySelectorAll("[data-toggles]").forEach(elem => {
      elem.addEventListener("click", () => popup(elem));
    });
    .popuptext {
      display: none;
    }
    
    .popuptext.show {
      display: block;
    }
    <p class='popup' data-toggles="#popup1">Willy the Kid
      <span class='popuptext' id='popup1'>
            During his turn, he can play any number of 'Bang!' cards.<br>(4 life points)
        </span>
    </p><br>
    
    <p class='popup' data-toggles="#popup2">Lucky Duke
      <span class='popuptext' id='popup2'>
            Each time he is required to 'Draw!', he flips the top two cards from the deck and chooses the result he prefers. Both cards are discarded afterwards.<br>(4 life points)
        </span>
    </p><br>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search