I cant use setTimeout and event.clientX in the same function without getting this error: "Uncaught RangeError: Maximum call stack size exceeded"
I cant use setTimeout and event.clientX in the same function without getting this error: "Uncaught RangeError: Maximum call stack size exceeded"
我想每隔一秒设置一个与光标位置相等的元素位置。但是一旦我在函数中包含 setTimout 属性,它就会停止工作并在日志中打印以下错误:"Uncaught RangeError: Maximum call stack size exceeded"。
我曾尝试 运行 没有超时的代码,但随后页面冻结。
这是我无法开始工作的代码:
function moveElement() {
while (true) {
x = event.clientX;
y = event.clientY;
document.getElementById("status").innerHTML = x + " " + y; //This line is not important
setTimeout(moveElement(), 1000);
document.getElementById("test").style.color = "blue";
document.getElementById("test").style.left = x + "px";
document.getElementById("test").style.top = y + "px";
}
};
当我尝试在函数外 运行 event.clientX 时也会出现此错误:"Uncaught TypeError: Cannot read property 'clientX' of undefined"
有人可以看看我的代码有什么问题,或者只是告诉我另一种方法让它工作(请不要 jQuery)?谢谢你。
/HamMan4Ever
你有这条线:
setTimeout(moveElement(), 1000);
应该是:
setTimeout(moveElement, 1000);
函数末尾的括号会立即调用它。所以这个函数只是一遍又一遍地调用自己。您想传递对超时应在指定时间后调用的函数的引用。
Uncaught RangeError: Maximum call stack size exceeded
您还应该删除 while(true) ,它将永远循环。这很可能是您收到上述错误的原因。如果您想每秒调用此函数,只需使用 setTimeout,它将等待指定的时间量,然后调用您传递给它的函数引用。
Uncaught TypeError: Cannot read property 'clientX' of undefined
发生这种情况是因为不存在事件变量。通常一个事件被传递给一个函数,该函数已作为某个事件的处理程序附加。
这是一个附加事件并以某种方式使用 clientX/clientY 的示例。也许它会帮助您理解和扩展它以完成您想做的任何事情:
Fiddle: http://jsfiddle.net/tqpvkjd9/
HTML:
<div id="test">some text</div>
JS:
function moveElement (event) {
var x = event.clientX;
var y = event.clientY;
var test = document.getElementById("test");
test.style.color = "blue";
test.style.left = x + "px";
test.style.top = y + "px";
};
document.addEventListener('mousemove', moveElement);
CSS:
div {
height: 100px;
width: 100px;
background: red;
position: absolute;
top: 0;
left: 0;
}
最后,您真的应该像我上面那样使用 var 声明 x 和 y。如果没有 var,它们将被假定为全局变量,这通常并不好。
setTimeout 的第一个参数必须是一个函数。当您使用像 moveElement()
这样的代码时,您是在 调用 函数(再次),而不是仅仅提供对它的引用。所以我认为你最好做这样的事情:
setTimeout(moveElement, 1000);
while (true)
循环导致您的页面冻结,因为它是一个永恒的循环;它会 运行 你的代码永远重复,不会给你的浏览器喘息的时间。可怜的东西。
此示例等到鼠标停止移动,然后等待一秒钟,然后应用新位置。
我可以创建另一个示例,每秒更新一次位置,尽管等待鼠标停止移动可能是个好主意。
此代码等待鼠标移动,然后清除任何现有的 运行 计时器,然后设置一个新计时器。它还捕获并存储有关鼠标移动的信息以备后用。
由于 mousemove 事件是一个重复事件(每当您移动鼠标时它都会触发一千次)这就是为什么每当鼠标移动时,所有计时器都会被清除以避免同时设置多个计时器。
这段代码的最终结果是,当你移动鼠标时,它会等到你停止移动鼠标,等待一秒钟,然后设置 div 坐标。
如果有什么我可以为您做的,请在评论中告诉我。
window.addEventListener('load',function(){//when the page loads
//initialize all variables.
var timer = false;
var updateTracking = false;
var x = 0;
var y = 0;
window.addEventListener('mousemove',function(e){//when the mouse is moved.
clearTimer();//clear the existing timer
updateTracking = true;//set the flag so that the if statement knows the mouse has been moved.
x = e.x;//get the X coord of the mouse move
y = e.y;//get the Y coord of the mouse move
setTimer();//set a timer for 1 second.
});
//the function that sets the timer.
function setTimer(){
//set the "timer" variable to a timer function
timer = window.setTimeout(function(){
if(updateTracking == true){//if the mouse has been moved
var elem = document.getElementById('theDiv');//get the element
updateTracking = false;//reset the flag since the element has been updated
elem.style.top = y+'px';//set the Y coord of the element
elem.style.left = x+'px';//set the X coord of the element
}
},1000);
}
function clearTimer(){//cleat timer function; clears any existing timers
window.clearTimeout(timer);//clear the timer
}
});
#theDiv{
width:30px;
height:30px;
background:red;
position:absolute;
}
<div id="theDiv"></div>
这是另一个代码片段,向您展示了 mousemove 事件的工作原理。只需打开您的控制台并移动鼠标...
window.onload = function(){
window.onmousemove = function(){
console.log('the mouse was moved');
};
};
我想每隔一秒设置一个与光标位置相等的元素位置。但是一旦我在函数中包含 setTimout 属性,它就会停止工作并在日志中打印以下错误:"Uncaught RangeError: Maximum call stack size exceeded"。
我曾尝试 运行 没有超时的代码,但随后页面冻结。
这是我无法开始工作的代码:
function moveElement() {
while (true) {
x = event.clientX;
y = event.clientY;
document.getElementById("status").innerHTML = x + " " + y; //This line is not important
setTimeout(moveElement(), 1000);
document.getElementById("test").style.color = "blue";
document.getElementById("test").style.left = x + "px";
document.getElementById("test").style.top = y + "px";
}
};
有人可以看看我的代码有什么问题,或者只是告诉我另一种方法让它工作(请不要 jQuery)?谢谢你。
/HamMan4Ever
你有这条线:
setTimeout(moveElement(), 1000);
应该是:
setTimeout(moveElement, 1000);
函数末尾的括号会立即调用它。所以这个函数只是一遍又一遍地调用自己。您想传递对超时应在指定时间后调用的函数的引用。
Uncaught RangeError: Maximum call stack size exceeded
您还应该删除 while(true) ,它将永远循环。这很可能是您收到上述错误的原因。如果您想每秒调用此函数,只需使用 setTimeout,它将等待指定的时间量,然后调用您传递给它的函数引用。
Uncaught TypeError: Cannot read property 'clientX' of undefined
发生这种情况是因为不存在事件变量。通常一个事件被传递给一个函数,该函数已作为某个事件的处理程序附加。
这是一个附加事件并以某种方式使用 clientX/clientY 的示例。也许它会帮助您理解和扩展它以完成您想做的任何事情:
Fiddle: http://jsfiddle.net/tqpvkjd9/
HTML:
<div id="test">some text</div>
JS:
function moveElement (event) {
var x = event.clientX;
var y = event.clientY;
var test = document.getElementById("test");
test.style.color = "blue";
test.style.left = x + "px";
test.style.top = y + "px";
};
document.addEventListener('mousemove', moveElement);
CSS:
div {
height: 100px;
width: 100px;
background: red;
position: absolute;
top: 0;
left: 0;
}
最后,您真的应该像我上面那样使用 var 声明 x 和 y。如果没有 var,它们将被假定为全局变量,这通常并不好。
setTimeout 的第一个参数必须是一个函数。当您使用像 moveElement()
这样的代码时,您是在 调用 函数(再次),而不是仅仅提供对它的引用。所以我认为你最好做这样的事情:
setTimeout(moveElement, 1000);
while (true)
循环导致您的页面冻结,因为它是一个永恒的循环;它会 运行 你的代码永远重复,不会给你的浏览器喘息的时间。可怜的东西。
此示例等到鼠标停止移动,然后等待一秒钟,然后应用新位置。 我可以创建另一个示例,每秒更新一次位置,尽管等待鼠标停止移动可能是个好主意。
此代码等待鼠标移动,然后清除任何现有的 运行 计时器,然后设置一个新计时器。它还捕获并存储有关鼠标移动的信息以备后用。 由于 mousemove 事件是一个重复事件(每当您移动鼠标时它都会触发一千次)这就是为什么每当鼠标移动时,所有计时器都会被清除以避免同时设置多个计时器。
这段代码的最终结果是,当你移动鼠标时,它会等到你停止移动鼠标,等待一秒钟,然后设置 div 坐标。
如果有什么我可以为您做的,请在评论中告诉我。
window.addEventListener('load',function(){//when the page loads
//initialize all variables.
var timer = false;
var updateTracking = false;
var x = 0;
var y = 0;
window.addEventListener('mousemove',function(e){//when the mouse is moved.
clearTimer();//clear the existing timer
updateTracking = true;//set the flag so that the if statement knows the mouse has been moved.
x = e.x;//get the X coord of the mouse move
y = e.y;//get the Y coord of the mouse move
setTimer();//set a timer for 1 second.
});
//the function that sets the timer.
function setTimer(){
//set the "timer" variable to a timer function
timer = window.setTimeout(function(){
if(updateTracking == true){//if the mouse has been moved
var elem = document.getElementById('theDiv');//get the element
updateTracking = false;//reset the flag since the element has been updated
elem.style.top = y+'px';//set the Y coord of the element
elem.style.left = x+'px';//set the X coord of the element
}
},1000);
}
function clearTimer(){//cleat timer function; clears any existing timers
window.clearTimeout(timer);//clear the timer
}
});
#theDiv{
width:30px;
height:30px;
background:red;
position:absolute;
}
<div id="theDiv"></div>
这是另一个代码片段,向您展示了 mousemove 事件的工作原理。只需打开您的控制台并移动鼠标...
window.onload = function(){
window.onmousemove = function(){
console.log('the mouse was moved');
};
};