奇怪的JavaScript行为,这里可能发生什么?

时间:2017-10-07 18:28:24

标签: javascript google-chrome

考虑以下javascript函数:

function bs_animate_percentage(elem,style,unit,from,to,time) {
    if(!elem) return;

    console.log("first elem", elem);
    var start = new Date().getTime(),
        timer = setInterval(function() {
            console.log("second elem", elem);
            console.log("time", time);
            var step = Math.min(1,(new Date().getTime()-start)/time);
            elem.style[style] = (from+step*(to-from))+unit;
            if(step == 1) clearInterval(timer);
        },25);
    elem.style[style] = from+unit;
}

此函数应为加载栏设置动画,它取自另一个stackOverflow问题。我想在动画中添加文本更改,我需要初始元素的父级。

当我运行此功能时,使用以下参数,控制台会记录以下值:

    bs_animate_percentage(document.getElementById("progress-bar"), 'width', '%', 0, 100, 60000);

    *** LOGS ***
    "first elem", <div....> (the selected div)
    "second elem", undefiend
    "time", 600000   

基本上,在main函数中,elem是已知的并且具有预期的值。但是在匿名函数中,elem被注销为undefined,如果我尝试获取它的父级,它也是未定义的,但是,style属性按预期工作,因为elem的宽度正在改变。我在chrome中遇到过这种情况,这可能是什么问题?

编辑:我也检查了Firefox,但奇怪的是,在第二个控制台日志中传回了正确的结果。这必须是Chrome特有的,但我不知道是什么......

EDIT2:更奇怪的是,当尝试在jsfiddle中复制此行为时,它不会持久存在,无论是在Chrome还是Firefox中。我应该在哪里寻找问题?

1 个答案:

答案 0 :(得分:1)

我很确定elem变量在此期间未设置。 我的预测是它有时可能会过去。 验证这一点的方法之一如下:

function bs_animate_percentage(elem,style,unit,from,to,time) {
    if(!elem) return;

    console.log("first elem", elem);
    var x = elem.cloneNode(true);
    var start = new Date().getTime(),
        timer = setInterval(function() {
            console.log("second elem", x);
            console.log("time", time);
            var step = Math.min(1,(new Date().getTime()-start)/time);
            elem.style[style] = (from+step*(to-from))+unit;
            if(step == 1) clearInterval(timer);
        },25);
    elem.style[style] = from+unit;
}

我相信这没关系。它会确认你的问题。 接下来将是如何解决它。 elem是dom元素还是其他元素? 它是用chrome修改的吗? 更好的方法是给这个元素一个id然后通过id获取它并设置它的样式如下,只是当你不想在你的代码中调试问题时。

function bs_animate_percentage(elem,style,unit,from,to,time) {
        if(!elem) return;

        console.log("first elem", elem);
        var x = elem.cloneNode(true).id;
        var start = new Date().getTime(),
            timer = setInterval(function() {
                // Or some similar logic
                x = document.getElementById(x);
                console.log("second elem", x);
                console.log("time", time);
                var step = Math.min(1,(new Date().getTime()-start)/time);
                elem.style[style] = (from+step*(to-from))+unit;
                if(step == 1) clearInterval(timer);
            },25);
        elem.style[style] = from+unit;
    }