我正在制作动画,其中有四个方向可被多次按下的按钮,以及“运行”按钮。按下“运行”按钮后,它将执行所有运动。
我遇到了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-->
我要寻找的是,如果我按两次右键,然后运行,它会进行两次移动,然后停止。
答案 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>