skip to Main Content

I have a div(.game-space) containing 6 child boxes, one of them is active box having (‘.active-Box) class having green background,

so when I click on active box its shift its class(.active-Box) to the next box that gives green background in this way it goes to all the way to last Box. Also I have restart button , when I click on it, the game should restart like the the active-box class gets tagged to first box and from here it shift again to the next Box and goes to all the way to end Box on clicking.

'use strict'
const allBox = document.querySelectorAll('.box');
const activeBox = document.querySelector('.active-box')
const restartButton = document.querySelector('.restart-button')
let active_box_index = activeBox_index_function();

slideBox(allBox[active_box_index]);



/* ======> code1  Anonymous function */
/* 
function slideBox(pass_active_box) {
  pass_active_box.addEventListener('click', function() {
    allBox[active_box_index].classList.remove('active-box')
    allBox[active_box_index + 1].classList.add('active-box')

    active_box_index = activeBox_index_function()
    slideBox(allBox[active_box_index]);
  })
} */


/* ======> code 2 , funtion defined oustside nad passed into EventListener*/

function sliderfunction() {
  allBox[active_box_index].classList.remove('active-box')
  allBox[active_box_index + 1].classList.add('active-box')

  active_box_index = activeBox_index_function()
  slideBox(allBox[active_box_index]);
}

function slideBox(pass_active_box) {
  pass_active_box.addEventListener('click', sliderfunction);
}


// active box index
function activeBox_index_function() {
  let index;
  allBox.forEach((el, indx) => {
    if (el.matches('.active-box')) {
      index = indx
    };
  })
  return index;
}

// when restart button clicked
restartButton.addEventListener('click', function () {
  allBox[active_box_index].classList.remove('active-box')
  allBox[0].classList.add('active-box')

  active_box_index = activeBox_index_function()
})
@import url('https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,200;0,300;0,400;0,600;0,700;0,800;0,900;1,800&display=swap');
@import url('https://fonts.cdnfonts.com/css/common-pixel');

* {
    padding: 0;
    margin: 0;
    box-sizing: border-box;
}

html {
    font-size: 62.5%;
    font-family: 'Poppins', sans-serif;
    color: black;
}

.game--section {
    height: 100vh;
    background-color: #252525;
    display: flex;
    justify-content: center;
    align-items: center;
}

.game-space {
    width: 80rem;
    height: 10rem;
    padding: 1rem;
    border-radius: 9px;
    background-color: #f5f5f5;
    display: grid;
    grid-template-columns: repeat(6, 1fr);
    gap: 1rem;
}

.box {
    background-color: tomato;
}

.active-box {
    background-color: #099268;
    cursor: pointer;
}

.restart-button {
    font-size: 3rem;
    cursor: pointer;
}
<body>

    <section class="game--section">
        <div class="game-space">
            <div class="box box1 active-box"></div>
            <div class="box box2"></div>
            <div class="box box3"></div>
            <div class="box box4"></div>
            <div class="box box5"></div>
            <div class="box box6"></div>
        </div>
        <div class="restart-button">🔁</div>
    </section>

    <script src="script.js"></script>
</body>

Here is the twist
I tried passing the same block of code to addEventListener as Anonymous function and Function defined outside passed to addEventListener. I see that both are working differently, where

code1) anonymous function block is adding incremental EventListener to the DOM element where it is skipping the boxes because of double event triggers.
code2) it is not incrementing the EventListener on DOM element, which working completely fine, where I even didn’t add removeEventListener is not DOM element.

Once, try offing the comment of code1 and code2 vice-versa and after 2 to 3 shifting of active-box class to next boxes click restart and trying try clicking them, you’ll get What I am doubting…

2

Answers


  1. It seems that when you try to add again a defined function to the event listener, it is not added, whereas anonymous functions are truly anonymous and when you try to add again the same code to the event listener, engine does not identify that as identical to previous function and hence multiple event listeners are being added. See MDN Web Docs for more info.

    It says:

    If the function or object is already in the list of event listeners
    for this target, the function or object is not added a second time.

    and:

    If a particular anonymous function is in the list of event listeners
    registered for a certain target, and then later in the code, an
    identical anonymous function is given in an addEventListener call, the
    second function will also be added to the list of event listeners for
    that target.

    Indeed, anonymous functions are not identical even if defined using
    the same unchanging source-code called repeatedly, even if in a loop.

    Login or Signup to reply.
  2. My english is really bad, but if I understand your issue…

    You have a problem in your sliderfunction()

    You don’t check if allBox[active_box_index + 1] exist

    So you may check this in the sliderfunction() or in the activeBox_index_function()

    Here bellow the snippet do the check in the sliderfunction() so you avoid the log :
    allBox[(active_box_index + 1)] is undefined"

    In this case when you reach the end of the boxes, the last box remains active until you click on the start button.

        'use strict'
        const allBox = document.querySelectorAll('.box');
        const activeBox = document.querySelector('.active-box')
        const restartButton = document.querySelector('.restart-button')
        let active_box_index = activeBox_index_function();
    
        slideBox(allBox[active_box_index]);
    
    
    
        /* ======> code1  Anonymous function */
        /*
        function slideBox(pass_active_box) {
          pass_active_box.addEventListener('click', function() {
            allBox[active_box_index].classList.remove('active-box')
            allBox[active_box_index + 1].classList.add('active-box')
    
            active_box_index = activeBox_index_function()
            slideBox(allBox[active_box_index]);
          })
        } */
    
    
        /* ======> code 2 , funtion defined oustside nad passed into EventListener*/
    
        function sliderfunction() {
            //
          allBox[active_box_index].classList.remove('active-box')
            if((allBox[active_box_index + 1]!=undefined)){
                allBox[active_box_index + 1].classList.add('active-box')
            }else{
                allBox[allBox.length-1].classList.add('active-box')
            }
          
                
          active_box_index = activeBox_index_function()
          slideBox(allBox[active_box_index]);
        }
    
        function slideBox(pass_active_box) {
          pass_active_box.addEventListener('click', sliderfunction);
        }
    
    
        // active box index
        function activeBox_index_function() {
          let index;
          allBox.forEach((el, indx) => {
            if (el.matches('.active-box')) {
              index = indx
            };
          })
          return index;
        }
    
        // when restart button clicked
        restartButton.addEventListener('click', function () {
          allBox[active_box_index].classList.remove('active-box')
          allBox[0].classList.add('active-box')
          active_box_index = activeBox_index_function()
        })
            * {
                padding: 0;
                margin: 0;
                box-sizing: border-box;
            }
    
            html {
                font-size: 62.5%;
                font-family: 'Poppins', sans-serif;
                color: black;
            }
    
            .game--section {
                height: 100vh;
                background-color: #252525;
                display: flex;
                justify-content: center;
                align-items: center;
            }
    
            .game-space {
                width: 80rem;
                height: 10rem;
                padding: 1rem;
                border-radius: 9px;
                background-color: #f5f5f5;
                display: grid;
                grid-template-columns: repeat(6, 1fr);
                gap: 1rem;
            }
    
            .box {
                background-color: tomato;
            }
    
            .active-box {
                background-color: #099268;
                cursor: pointer;
            }
    
            .restart-button {
                font-size: 3rem;
                cursor: pointer;
            }   
        <section class="game--section">
            <div class="game-space">
                <div class="box box1 active-box"></div>
                <div class="box box2"></div>
                <div class="box box3"></div>
                <div class="box box4"></div>
                <div class="box box5"></div>
                <div class="box box6"></div>
            </div>
            <div class="restart-button">🔁</div>
        </section>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search