使用动画时,clearInterval不会停止触发的事件,或者第二个动画无法运行

时间:2019-01-30 07:36:54

标签: javascript timer dom-events eventtrigger

我正在制作动画,其中有四个方向可被多次按下的按钮,以及“运行”按钮。按下“运行”按钮后,它将执行所有运动。

我遇到了22类问题,永远触发以太事件,动画永不停止,或者动画只运行一次。

我尝试了多种解决方案,现在决定使用触发器,程序的工作方式是将移动添加到数组中,然后在for循环中触发,触发机制设置的触发器会在较短的间隔内朝该方向触发。

下面的代码仅针对按钮right完成,以重现该问题,只需单击两次并按run,您将明白我的意思,我还添加了指示问题的控制台调试和一个Jsfiddle {{ 3}} 如果要在仅触发一次的地方重现,请检查此提琴https://jsfiddle.net/0rxs9jpy/1/或取消注释行//if (r) return;

var moves = [];
leftpx = 0;
downpx = 0;
uppx = 0;
rightpx = 0;
var up = function() {

  moves.push('up')

}

var down = function() {

  moves.push('down')

}

var left = function() {

  moves.push('left')

}

var right = function() {

  moves.push('right')

}
document.addEventListener("moveRight", function(e) {

});
document.addEventListener("stopRight", function(e) {
  console.log(e.detail);
  clearInterval(e.detail);

});

var Run = function() {


  for (var i = 0; i < moves.length; i++) {

    if (moves[i] == 'up') {
      document.getElementById('square').style.top = setInterval(myMove(), 3000);
    };
    if (moves[i] == 'left') {
      document.getElementById('square').style.left = myMove3()
    };
    if (moves[i] == 'down') {
      document.getElementById('square').style.top = myMove2()
    };
    if (moves[i] == 'right') {

      //if (r) return;
      var r = setInterval(function() {
        var event = new CustomEvent("moveRight", {
          "detail": "Example of an event"
        });
        document.dispatchEvent(event)
        var event1 = new CustomEvent("stopRight", {
          "detail": r
        });
        document.dispatchEvent(event1);
      }, 300);
    };
  }
  moves = [];
}

function myMove4(pos) {
  var elem = document.getElementById("square");
  var id = setInterval(frame, 5);
  var i = elem.style.left == '' ? 0 : parseInt(elem.style.left.replace('px', ''));
  pos = elem.style.left == '' ? pos : pos + i;

  console.log(i + ' ' + pos);

  function frame() {
    if (elem.style.left == pos + 'px') {
      clearInterval(id);
    } else {
      //  pos++;

      elem.style.left = (i++) + "px";


    }
  }
}
#square {
  width: 50px;
  height: 50px;
  background-color: blue;
  position: relative;
  animation: myfirst 5s linear 2s infinite alternate;
}
<input type='button' value='up' onclick='up()'></input>
<input type='button' value='down' onclick='down()'></input>
<input type='button' value='left' onclick='left()'></input>
<input type='button' value='right' onclick='right()'></input>
<input type='button' value='Run' onclick='Run()'></input>

<div id="square"></div>

<!--https://jsfiddle.net/0rxs9jpy-->

我要寻找的是,如果我按两次右键,然后运行,它会进行两次移动,然后停止。

1 个答案:

答案 0 :(得分:0)

一种方法是使用javascript Promises

工作示例如下:

    <html>
    <head></head>
    <body>
    <input type = 'button' value = 'up' onclick = 'up()'></input>
    <input type = 'button' value = 'down' onclick = 'down()'></input>
    <input type = 'button' value = 'left' onclick = 'left()'></input>
    <input type = 'button' value = 'right' onclick = 'right()'></input>
    <input type = 'button' value = 'Run' onclick = 'Run()'></input>
    <br />
    <br />
    <br />
    <div id = "square"></div>
    <script>
          var moves = [];
          leftpx = 0;
          downpx = 0;
          uppx = 0;
          rightpx = 0;
          var up = function() {

              moves.push('up')

          }

          var down = function() {

              moves.push('down')

          }

          var left = function() {

              moves.push('left')

          }

          var right = function() {

              moves.push('right')

          }


          function setTimeoutPromise(ms) {
              return new Promise(function(resolve) {
                  setTimeout(resolve, ms);
              });
          }

          function foo(item, ms) {
              return function() {
                  return setTimeoutPromise(ms).then(function() {
                      if (item == 'right') {
                          myMove4(100)
                      };
                      if (item == 'down') {
                          myMove2(100)
                      };
                      if (item == 'left') {
                          myMove3(-100)
                      };
                      if (item == 'up') {
                          myMove(-100)
                      };
                  });
              };
          }


          function bar() {
              var chain = Promise.resolve();
              moves.forEach(function(el, i) {
                  chain = chain.then(foo(el,  600));
              });
              return chain;
          }

          bar().then(function() {});


          var Run = function() {
              bar();
              moves = [];
          }

          function myMove(pos) {
              var elem = document.getElementById("square");
              var id = setInterval(frame, 5);
              var i = elem.style.top == '' ? 0 : parseInt(elem.style.top.replace('px', ''));
              pos = elem.style.top == '' ? pos : pos + i;

              console.log(i + ' ' + pos);

              function frame() {
                  if (elem.style.top == pos + 'px') {
                      clearInterval(id);
                  } else {


                      elem.style.top = (i--) + "px";


                  }
              }
          }

          function myMove2(pos) {
              var elem = document.getElementById("square");
              var id = setInterval(frame, 5);
              var i = elem.style.top == '' ? 0 : parseInt(elem.style.top.replace('px', ''));
              pos = elem.style.top == '' ? pos : pos + i;

              console.log(i + ' ' + pos);

              function frame() {
                  if (elem.style.top == pos + 'px') {
                      clearInterval(id);
                  } else {
                      //  pos++;

                      elem.style.top = (i++) + "px";


                  }
              }
          }

          function myMove3(pos) {
              var elem = document.getElementById("square");
              var id = setInterval(frame, 5);
              var i = elem.style.left == '' ? 0 : parseInt(elem.style.left.replace('px', ''));
              pos = elem.style.left == '' ? pos : pos + i;

              console.log(i + ' ' + pos);

              function frame() {
                  if (elem.style.left == pos + 'px') {
                      clearInterval(id);
                  } else {
                      //  pos++;

                      elem.style.left = (i--) + "px";


                  }
              }
          }


          function myMove4(pos) {
              var elem = document.getElementById("square");
              var id = setInterval(frame, 5);
              var i = elem.style.left == '' ? 0 : parseInt(elem.style.left.replace('px', ''));
              pos = elem.style.left == '' ? pos : pos + i;

              console.log(i + ' ' + pos);

              function frame() {
                  if (elem.style.left == pos + 'px') {
                      clearInterval(id);
                  } else {
                      //  pos++;

                      elem.style.left = (i++) + "px";


                  }
              }
          }
    </script>
    <style>



    #square{
  
    width: 50px;
    height: 50px;
    background-color: blue;
    position: relative;
    animation: myfirst 5s linear 2s infinite alternate;
  
    }

    </style>


    </body>
    </html>