1

我想一一打印数字 1 到 4 以下是我的代码:

脚本

<script>
$(document).ready(function(){
var b=1;
function cal(){

$('#print').html(b + '<br/>');
b++;
};
setInterval("cal()",5000);
})
</script>

HTML

<div id="print"></div>

但它不起作用,显示以下错误:

未捕获的 ReferenceError:未定义 cal

为什么会这样,我该如何解决?

4

3 回答 3

3

修复

如何使用setInterval

这是使用的正确方法(稍后解释)setInterval()

setInterval(cal, 5000);

编写此代码的一种可能方法

$(document).ready(function(){
    var b = 0;
    function cal() {
        b++;
        $('#print').html(b + '<br/>');
        if (b === 4) {
            clearInterval(to);
        }
    };
    var to = setInterval(cal, 5000);
});​

jsFiddle 演示

当然还有改进的地方,比如你可以缓存$('#print'). 您不需要每次都获取它。

...
var $print = $('#print'); //save it to a variable
function cal() {
    b++;
    $print.html(b + '<br/>'); //use the cached version
    ...

问题

字符串而不是函数 -> eval

虽然从技术上讲,您可以将字符串setInterval作为其第一个参数传递,但它等同于使用eval. 正如我们所知,eval是邪恶的,只有在你真的知道自己在做什么的情况下才使用它。这同样适用于setTimeout。无论您在 w3schools和其他过时的资源上看到了什么,都不应将字符串传递给这些方法。传递一个函数。

evalwith的范围setInterval

eval使用with的问题之一setInterval()是它试图在全局范围内的字符串中运行您的代码,这就是您收到错误的原因。setInterval在 上定义window,并在其范围内运行。您在传递给的闭包的范围内document.ready(),并且函数在此范围内定义。eval试图在不存在的全局范围内找到它。

于 2012-05-18T10:12:06.917 回答
2

你也可以试试这个:

var b = 1;
function call() {
    $('#print').append(b + '<br/>');
    b++;
    setTimeout(function() {
        if (b < 5) call();
    },5000);
};
call();

演示

于 2012-05-18T10:25:56.537 回答
1

cal()与其提供对函数的字符串引用,不如提供setInterval函数引用本身:

var b = 1;    
function cal() {
    $('#print').html(b + '<br/>');
    b++;
};
setInterval(cal, 1000);

示例小提琴


另外,你当前的代码会在 4 次迭代后继续调用区间,所以有点浪费。您可以将其更改为具有延迟的 for 循环,或者在 4 次迭代后销毁对计时器的引用,如下所示:

var b = 1;    
function cal() {
    $('#print').html(b + '<br/>');
    b++;
    if (b > 4)
        clearInterval(timer);
};
var timer = setInterval(cal, 1000);

示例小提琴

于 2012-05-18T10:10:14.127 回答