requestAnimationFrame 的问题
Issues with requestAnimationFrame
我有一个问题:
document.querySelector('div').addEventListener('mousedown', function(){
hello = true
document.body.addEventListener('mousemove', function(e){
if (hello) {
document.querySelector('div').style.left = (e.clientX - 12.5) + 'px'
document.querySelector('div').style.top = (e.clientY - 12.5) + 'px'
}
})
this.addEventListener('mouseup', function(e){
hello = false
posY = Math.floor(parseInt(this.style.top))
function Fall() {
posY++
document.querySelector('div').style.top = posY + 'px'
if (posY != parseInt(window.innerHeight) - 25) requestAnimationFrame(Fall)
}
Fall()
})
})
body {
margin:0;
position:absolute;
height:100vh;
width:100vw;
overflow:hidden
}
div {
position:absolute;
height:25px;
width:25px;
border:1px #000 solid;
bottom:0
}
div:hover {
cursor:pointer;
}
<div></div>
在这段代码中(also on jsFiddle,当我放下 div 时,我希望 div 掉落,并停在地面上。
第一次成功。但是, requestAnimationFrame
更快,就像第一个没有完成......?在那之后,div 并没有停在地面上:(
我必须使用 setInterval
而不是 requestAnimationFrame
吗?
问题是您要添加 mouseup
处理程序 每次 div 收到 mousedown
。您只想执行一次,因此请将其移出 mousedown
处理程序。因此,您在第二次调用时设置动画两次(因为两个处理程序都响应),在第三次调用三次(因为所有三个处理程序都响应)等。并且由于多个处理程序正在更新 poxY
,它不会停止不再在地面上了,因为 !=
检查失败,除了其中一个。 (请参阅代码段下的更多注释。)
document.querySelector('div').addEventListener('mousedown', function() {
hello = true
document.body.addEventListener('mousemove', function(e) {
if (hello) {
document.querySelector('div').style.left = (e.clientX - 12.5) + 'px'
document.querySelector('div').style.top = (e.clientY - 12.5) + 'px'
}
})
})
// Moved the below
document.querySelector('div').addEventListener('mouseup', function(e) {
hello = false
posY = Math.floor(parseInt(this.style.top))
function Fall() {
posY++
document.querySelector('div').style.top = posY + 'px'
if (posY != parseInt(window.innerHeight) - 25) requestAnimationFrame(Fall)
}
Fall()
})
body {
margin: 0;
position: absolute;
height: 100vh;
width: 100vw;
overflow: hidden
}
div {
position: absolute;
height: 25px;
width: 25px;
border: 1px #000 solid;
bottom: 0
}
div:hover {
cursor: pointer;
}
<div class="square"></div>
其他一些观察:
- 您的代码正在成为 The Horror of Implicit Globals* 的牺牲品——声明您的变量
- 与其一直重新查询 DOM,不如查询 DOM 以获得
div
一次 ], 并记在一个变量中
* (披露:这是我贫血的小博客上的 post)
只要单击 div(鼠标按下),就会分配另一个侦听器。当你停止点击时,这些监听器都是按顺序执行的,所以在第二次点击时,会有两次循环运行,第三次之后会有三次循环运行,依此类推。您可以只分配一次监听器:
var hello,posY;
document.querySelector('div').addEventListener('mousedown', function(){
hello = true;
});
document.body.addEventListener('mousemove', function(e){
if (hello) {
document.querySelector('div').style.left = (e.clientX - 12.5) + 'px';
document.querySelector('div').style.top = (e.clientY - 12.5) + 'px';
}
});
document.querySelector('div').addEventListener('mouseup', function(e){
hello = false;
posY = Math.floor(parseInt(this.style.top));
function Fall() {
posY++;
document.querySelector('div').style.top = posY + 'px';
if (posY < parseInt(window.innerHeight) - 25) requestAnimationFrame(Fall);
}
Fall();
});
并且请始终以分号结束语句...
我有一个问题:
document.querySelector('div').addEventListener('mousedown', function(){
hello = true
document.body.addEventListener('mousemove', function(e){
if (hello) {
document.querySelector('div').style.left = (e.clientX - 12.5) + 'px'
document.querySelector('div').style.top = (e.clientY - 12.5) + 'px'
}
})
this.addEventListener('mouseup', function(e){
hello = false
posY = Math.floor(parseInt(this.style.top))
function Fall() {
posY++
document.querySelector('div').style.top = posY + 'px'
if (posY != parseInt(window.innerHeight) - 25) requestAnimationFrame(Fall)
}
Fall()
})
})
body {
margin:0;
position:absolute;
height:100vh;
width:100vw;
overflow:hidden
}
div {
position:absolute;
height:25px;
width:25px;
border:1px #000 solid;
bottom:0
}
div:hover {
cursor:pointer;
}
<div></div>
在这段代码中(also on jsFiddle,当我放下 div 时,我希望 div 掉落,并停在地面上。
第一次成功。但是, requestAnimationFrame
更快,就像第一个没有完成......?在那之后,div 并没有停在地面上:(
我必须使用 setInterval
而不是 requestAnimationFrame
吗?
问题是您要添加 mouseup
处理程序 每次 div 收到 mousedown
。您只想执行一次,因此请将其移出 mousedown
处理程序。因此,您在第二次调用时设置动画两次(因为两个处理程序都响应),在第三次调用三次(因为所有三个处理程序都响应)等。并且由于多个处理程序正在更新 poxY
,它不会停止不再在地面上了,因为 !=
检查失败,除了其中一个。 (请参阅代码段下的更多注释。)
document.querySelector('div').addEventListener('mousedown', function() {
hello = true
document.body.addEventListener('mousemove', function(e) {
if (hello) {
document.querySelector('div').style.left = (e.clientX - 12.5) + 'px'
document.querySelector('div').style.top = (e.clientY - 12.5) + 'px'
}
})
})
// Moved the below
document.querySelector('div').addEventListener('mouseup', function(e) {
hello = false
posY = Math.floor(parseInt(this.style.top))
function Fall() {
posY++
document.querySelector('div').style.top = posY + 'px'
if (posY != parseInt(window.innerHeight) - 25) requestAnimationFrame(Fall)
}
Fall()
})
body {
margin: 0;
position: absolute;
height: 100vh;
width: 100vw;
overflow: hidden
}
div {
position: absolute;
height: 25px;
width: 25px;
border: 1px #000 solid;
bottom: 0
}
div:hover {
cursor: pointer;
}
<div class="square"></div>
其他一些观察:
- 您的代码正在成为 The Horror of Implicit Globals* 的牺牲品——声明您的变量
- 与其一直重新查询 DOM,不如查询 DOM 以获得
div
一次 ], 并记在一个变量中
* (披露:这是我贫血的小博客上的 post)
只要单击 div(鼠标按下),就会分配另一个侦听器。当你停止点击时,这些监听器都是按顺序执行的,所以在第二次点击时,会有两次循环运行,第三次之后会有三次循环运行,依此类推。您可以只分配一次监听器:
var hello,posY;
document.querySelector('div').addEventListener('mousedown', function(){
hello = true;
});
document.body.addEventListener('mousemove', function(e){
if (hello) {
document.querySelector('div').style.left = (e.clientX - 12.5) + 'px';
document.querySelector('div').style.top = (e.clientY - 12.5) + 'px';
}
});
document.querySelector('div').addEventListener('mouseup', function(e){
hello = false;
posY = Math.floor(parseInt(this.style.top));
function Fall() {
posY++;
document.querySelector('div').style.top = posY + 'px';
if (posY < parseInt(window.innerHeight) - 25) requestAnimationFrame(Fall);
}
Fall();
});
并且请始终以分号结束语句...