EventListener 的匿名函数和传递给 EventListener 的定义函数是否工作不同?

问题描述 投票:0回答:2

我有一个包含 6 个子框的 div(.game-space),其中一个是具有绿色背景的 ('.active-Box) 类的活动框,

所以当我点击活动框时,它会将它的类(.active-Box)移动到下一个给出绿色背景的框,这样它就会一直到最后一个框。我也有重新启动按钮,当我点击它时,游戏应该重新启动,就像活动框类被标记到第一个框,然后从这里它再次转移到下一个框,并在点击时一直到结束框。

'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>

转折来了 我尝试将相同的代码块作为匿名函数传递给 addEventListener,并将外部定义的函数传递给 addEventListener。我看到两者的工作方式不同,其中\

code1) 匿名功能块正在向 DOM 元素添加增量 EventListener,因为双事件触发,它会跳过这些框。 code2)它没有增加 DOM 元素上的 EventListener,它工作得很好,我什至没有添加 removeEventListener 不是 DOM 元素。

一次,尝试关闭 code1 和 code2 的注释,反之亦然,在将活动框类移动到下一个框 2 到 3 次后,单击重新启动并尝试单击它们,你会得到我所怀疑的......

javascript addeventlistener onclicklistener
2个回答
2
投票

似乎当您尝试再次向事件侦听器添加已定义的函数时,它不会被添加,而匿名函数是真正匿名的,当您尝试再次向事件侦听器添加相同的代码时,引擎不会将其识别为与以前的功能相同,因此添加了多个事件侦听器。有关更多信息,请参阅MDN Web Docs

上面写着:

如果函数或对象已经在事件监听器列表中 对于这个目标,函数或对象不会被第二次添加。

和:

如果一个特定的匿名函数在事件监听器列表中 为某个目标注册,然后在代码中,一个 在 addEventListener 调用中给出相同的匿名函数, 第二个函数也将添加到事件侦听器列表中 那个目标。

事实上,即使使用定义,匿名函数也不相同 重复调用相同的不变源代码,即使在循环中也是如此。


0
投票

我的英语真的很糟糕,但如果我理解你的问题...

你有问题

sliderfunction()

你不检查

allBox[active_box_index + 1]
是否存在

所以你可以在

sliderfunction()
activeBox_index_function()

中检查这个

在下面的代码片段中检查

sliderfunction()
,这样你就可以避免日志:
allBox[(active_box_index + 1)] is undefined"

在这种情况下,当您到达框的末尾时,最后一个框将保持活动状态,直到您单击开始按钮。

    '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>

© www.soinside.com 2019 - 2024. All rights reserved.