未捕获的 RangeError:超出最大调用堆栈大小和未捕获的 TypeError
2016-03-09
3106
我有这个函数
function flicker(length) {
$("p:nth-child(" + (Math.random() * length) + ")").toggleClass('off');
setTimeout(flicker(length), Math.random()*1000);
}
上面的代码给了我错误
Uncaught RangeError: Maximum call stack size exceeded
我还想知道当我使用
document.querySelectorAll("p:nth-child(" + (Math.random() * length) + ")").classList.toggle('off');
时是否有任何方法可以用 JavaScript 切换类,我得到了错误
Uncaught TypeError: Cannot read property 'toggle' of undefined
我该如何解决这些问题?
谢谢。
3个回答
调试后,我发现了 2 个问题。
-
Math.random() * length
返回一个浮点数,因此需要四舍五入。 -
setTimeout
可以在延迟后通过传递length
参数来接受函数
window.setTimeout(func, [delay, param1, param2, ...]);
function flicker(length) {
$("p:nth-child(" + Math.round(Math.random() * length) + ")").toggleClass('off');
setTimeout(flicker, Math.random() * 1000, length);
}
flicker(5)
.off {
color: white;
font-weight: bold;
background-color: black
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>1</p>
<p>2</p>
<p>3</p>
<p>4</p>
BenG
2016-03-09
使用 setTimout 时,必须将
flicker(length)
包装在一个函数中,如下所示:
function flicker(length) {
$("p:nth-child(" + (Math.random() * length) + ")").toggleClass('off');
setTimeout(function(){flicker(length);}, Math.random()*1000);
}
否则,它总是会立即被调用,导致如下结果:
function foo(){
foo();
}
foo();
这只会创建一个无限循环,并会导致与您描述的相同的堆栈错误。
Michael Kunst
2016-03-09
出现此问题的原因是您在无限循环中调用
flicker()
,将其结果设置为
setTimeout
,而不是传递其引用。您需要为
setTimeout()
调用提供一个匿名函数。试试这个:
function flicker(length) {
$("p:nth-child(" + (Math.random() * length) + ")").toggleClass('off');
setTimeout(function() {
flicker(length)
}, Math.random()*1000);
}
Rory McCrossan
2016-03-09