如何在 setTimeout 期间停止点击效果?

How to stop effect of click during setTimeout?

我有一个简单的函数,它每 x 秒改变 divs 的不透明度。 当我点击“暂停按钮”时,这个按钮在这个循环中暂停,并获得当前 div 的颜色。当我第二次单击此按钮时,循环会在 setTimeout 后重新开始播放。 我的问题是,当我多次单击(快速)按钮时,循环中存在错误。 我的条件不行。

是否有解决方案可以在 setTimeout 期间使用 stopPropagatione.preventDefault 或其他方式停止点击效果?

var j = 0;
var myElements = document.querySelectorAll('.div_child');
var myButton = document.querySelector('.my_button');

var colorArray = []
for (let i = 0; i < myElements.length; i++) {
  let currentColor = getComputedStyle(myElements[i]).backgroundColor;
  colorArray[i] = currentColor;
}

function my_fonction() {
  myElements[j].style.opacity = 1;
  for (let k = 0; k < myElements.length; k++) {
    if (k != j) {
      myElements[k].style.opacity = 0;
    }
  }
  j++;
  if (j == myElements.length) {
    j = 0
  }
  playForbidden = false;
}

function setIntervalAndExecuteFn(fn, t) {
  fn();
  return (setInterval(fn, t));
}

var myIndice = j;
var myIntervalId = setIntervalAndExecuteFn(my_fonction, 1000);
var play = true;
var playForbidden = false;

myButton.addEventListener('click', function() {
  if (playForbidden == false) {
    if (play == true) {
      play = false;
      clearInterval(myIntervalId);
      if (j == 0) {
        myIndice = myElements.length - 1;
      } else {
        myIndice = j - 1;
      }
      myButton.style.backgroundColor = colorArray[myIndice]
    } else {
      play = true;
      myButton.style.backgroundColor = 'transparent';
      setTimeout(function() {
        myIntervalId = setIntervalAndExecuteFn(my_fonction, 1000);
      }, 500);
    }
    playForbidden == true;
  } else {
    return;
  }
});
.div_parent {
  position: relative;
  width: 500px;
  height: 300px;
  border: 1px solid black;
}

.my_button {
  width: 300px;
  height: 100px;
  border: 1px solid black;
  font-family: Arial, Helvetica, sans-serif;
  font-weight: bold;
  font-size: 20px;
  padding: 20px;
  color: black;
}

.div_child {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  margin: auto;
  width: 500px;
  height: 300px;
}

.div_child_one {
  opacity: 0;
  background-color: red;
}

.div_child_two {
  opacity: 0;
  background-color: green;
}

.div_child_three {
  opacity: 0;
  background-color: violet;
}

.div_child_four {
  opacity: 0;
  background-color: rgb(104, 104, 104);
}
<div class="div_parent">
  <div class="div_child div_child_one"></div>
  <div class="div_child div_child_two"></div>
  <div class="div_child div_child_three"></div>
  <div class="div_child div_child_four"></div>
</div>
<div class="my_button">PAUSE BUTTON</div>

您的代码中的问题是 setTimeout 函数。当您执行 setTimeout 时,您所说的是“在 0.5 秒内开始间隔”。但问题是,如果您非常快(0.5 秒内)再次单击暂停,则此命令不会停止。您可以做的是在每次单击按钮时清除超时。这样就可以取消命令“0.5秒后开始间隔”了。

您可以在下面看到我的意思的工作片段:

var j = 0;
var myElements = document.querySelectorAll('.div_child');
var myButton = document.querySelector('.my_button');

var colorArray = []
for(let i=0; i<myElements.length; i++){
    let currentColor = getComputedStyle(myElements[i]).backgroundColor;
    colorArray[i] = currentColor;
}

function my_fonction(){ 
    myElements[j].style.opacity = 1;
    for(let k = 0; k < myElements.length; k++){ 
        if(k!=j){  
            myElements[k].style.opacity = 0;
        }
    }
    j++;
    if(j == myElements.length){ j = 0}
    playForbidden = false;
}

function setIntervalAndExecuteFn(fn, t){
    fn();
    return(setInterval(fn, t));  
}

var myIndice = j;
var myIntervalId = setIntervalAndExecuteFn(my_fonction, 1000);
var myTimeoutId;
var play = true;
var playForbidden = false;

myButton.addEventListener('click', function(){
    clearTimeout(myTimeoutId);
    if(playForbidden == false){
        if(play == true){
            play = false;
            clearInterval(myIntervalId);
            if(j == 0){
                myIndice = myElements.length-1;
            }else{
                myIndice = j-1;
            }
            myButton.style.backgroundColor = colorArray[myIndice]
        }else{
            play = true;
            myButton.style.backgroundColor = 'transparent';
            myTimeoutId = setTimeout(function() {
                myIntervalId = setIntervalAndExecuteFn(my_fonction, 1000);
            }, 500);
        }
        playForbidden == true;
    }else{
        return;
    }
});
.div_parent{
    position: relative;
    width: 500px;
    height: 300px;
    border: 1px solid black;
}
.my_button{
    width: 300px;
    height: 100px;
    border: 1px solid black;
    font-family: Arial, Helvetica, sans-serif;
    font-weight: bold;
    font-size: 20px;
    padding: 20px;
    color: black;
}
.div_child{
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    margin: auto;
    width: 500px;
    height: 300px;
}
.div_child_one{
    opacity: 0;
    background-color: red;
}
.div_child_two{
    opacity: 0;
    background-color: green;
}
.div_child_three{
    opacity: 0;
    background-color: violet;
}
.div_child_four{
    opacity: 0;
    background-color: rgb(104, 104, 104);
}
<div class="div_parent">
    <div class="div_child div_child_one"></div>
    <div class="div_child div_child_two"></div>
    <div class="div_child div_child_three"></div>
    <div class="div_child div_child_four"></div>
</div>
<div class="my_button">PAUSE BUTTON</div>