函数多次触发

时间:2021-04-27 14:07:01

标签: javascript dom-events

有人可以帮我解决这段 Javascript 问题吗?

我正在尝试制作某种“打地鼠”游戏,这就是我想出的;我设置了一种方法来跟踪分数,每次用户单击弹出的图片时都会添加 1(分数++)。我的问题是代码运行函数的次数比需要的多——例如,如果我点击弹出的第一个图像,将 +1 添加到分数的函数触发一次,如果我点击第二个,函数触发两次,三次三次,等等......

我做错了什么?

//gid
const grid = document.querySelector('.grid');
//score display value
const scoreValue = document.querySelector('#scoreValue');
//score
let score = 0;

const timer = setInterval(() => {

    //output random number
    let output = Math.floor(Math.random() * 16);
    //select hole
    let hole = document.getElementById(output);

    hole.innerHTML = '<img src="img/kiseki.png" alt=""></img>';
    
    setTimeout(() => {
        hole.innerHTML = '';
    }, 2000);

    grid.addEventListener('click', e => {
        if (e.target.tagName === "IMG") {
            score++;
            scoreValue.textContent = score;
            console.log(score);
            hole.innerHTML = '';
        }
    });
}, 4000);

3 个答案:

答案 0 :(得分:1)

由于您每次间隔运行时都会添加一个新的 eventListener,因此为了解决您的问题,只需在开始弹出 moles 的 setInterval 之前添加一次即可。

示例代码:


const grid = document.querySelector('.grid');
const scoreValue = document.querySelector('#scoreValue');
const newMoleTimer = 4000;
const moleTimeout = 2000
let score = 0;
let hole;

grid.addEventListener('click', e => {
  if (e.target.tagName === "IMG") {
    score++;
    scoreValue.textContent = score;
    if(hole) hole.innerHTML = '';
  }
});
    

const timer = setInterval(() => {
    let output = Math.floor(Math.random() * 16);
    hole = document.getElementById(output);

    hole.innerHTML = '<img src="img/kiseki.png" alt=""></img>';
    
    setTimeout(() => {
        hole.innerHTML = '';
    }, moleTimeout);
}, newMoleTimer);

*根据@Meika 评论更新代码

答案 1 :(得分:0)

您需要将 eventlistener 与 settimer 函数分开。

在这个例子中,我创建了带有颜色的 div 元素。只有蓝色得分,并且只能得分 pr。计时器。

//gid
const grid = document.querySelector('#grid');
//score display value
const scoreValue = document.querySelector('#scoreValue');
//score
let score = 0;

grid.addEventListener('click', e => {
  if (e.target.score) {
    score++;
    scoreValue.textContent = score;
    e.target.score = false;
  }
});

const timer = setInterval(() => {

  //output random number
  let output = 1 + Math.floor(Math.random() * 3);
  //select hole

  let hole = document.querySelector(`div.box:nth-child(${output})`)
  hole.classList.add('blue');
  hole.score = true;

  setTimeout(() => {
    hole.classList.remove('blue');
    hole.score = false;
  }, 1000);


}, 2000);
div#grid {
display: flex;
}
div.box {
  width: 100px;
  height: 100px;
  border: thin solid black;
  background-color: red;
}

div.blue {
  background-color: blue;
}
<div id="grid">
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
  <div class="box"></div>
</div>
<div id="scoreValue"></div>

答案 2 :(得分:0)

重写,一个鼹鼠是一个DOM元素,在加载时将点击事件附加到它然后,在游戏计时器中你只需要选择一个随机的鼹鼠并切换一个类,在点击事件中你可以检查该类,如果有那么痣一定是出现了,加分。

例如:

const moles = document.querySelectorAll('.grid .mole')
const hitScore = document.querySelector('.score .hit')
const missScore = document.querySelector('.score .miss')
const gameOver = document.querySelector('.gameover')

let score = {
  hit: 0,
  miss: 0
}

// assign clicks to all moles
moles.forEach((elm) => {
  elm.addEventListener('click', e => {
    if (e.target.classList.contains('show')) {
      hitScore.textContent = ++score.hit
      e.target.classList.remove('show')
    }
  })
})

// game timer
const timer = setInterval(() => {

  // get random mole element
  const randMole = moles[Math.floor(Math.random() * moles.length)]

  // check if has class, i.e miss
  if (randMole.classList.contains('show')) {
    missScore.textContent = ++score.miss
  }

  // toggle show
  randMole.classList.toggle('show')

  // 5 misses and game over
  if (score.miss >= 5) {
    clearInterval(timer)
    gameOver.style.display = 'block'
  }
}, 1000)
.grid {
  width: 310px;
  height: 310px;
  background-image: url(https://i.imgur.com/s6lUgud.png);
  position: relative
}

.mole {
  position: absolute;
  width: 100px;
  height: 100px
}

.mole.show {
  background-image: url(https://i.imgur.com/uScpWV4.png);
  background-repeat: no-repeat;
  background-size: 48px 51px;
  background-position: center
}

.mole:nth-of-type(1) {
  top: 0;
  left: 0
}

.mole:nth-of-type(2) {
  top: 0;
  left: 108px
}

.mole:nth-of-type(3) {
  top: 0;
  left: 214px
}

.mole:nth-of-type(4) {
  top: 100px;
  left: 0
}

.mole:nth-of-type(5) {
  top: 100px;
  left: 108px
}

.mole:nth-of-type(6) {
  top: 100px;
  left: 214px
}

.mole:nth-of-type(7) {
  top: 200px;
  left: 0px
}

.mole:nth-of-type(8) {
  top: 200px;
  left: 107px
}

.mole:nth-of-type(9) {
  top: 200px;
  left: 214px
}

.gameover {
  display: none;
  color: red
}
<div class="score">
  <strong>Score:</strong> Hit:
  <span class="hit">0</span> Miss:
  <span class="miss">0</span>
</div>
<div class="gameover">Game Over</div>
<div class="grid">
  <div class="mole"></div>
  <div class="mole"></div>
  <div class="mole"></div>
  <div class="mole"></div>
  <div class="mole"></div>
  <div class="mole"></div>
  <div class="mole"></div>
  <div class="mole"></div>
  <div class="mole"></div>
</div>