JavaScript:Setinterval只运行一次?

时间:2013-07-27 21:08:58

标签: javascript setinterval

我试图让show按钮带回h1标签,但在达到不透明度后停止:0.1而不是一直持续到不透明度:1。

我已经尝试过几个小时在Firebug上进行调试,但似乎无法破解它。请帮忙。

<!DOCTYPE html>
<html>
<head>
<title>Flesh and Bone</title>
</head>
<body>
<h1>Flesh and Bone</h1>
<button id="fade">Fade</button>
<button id="show">Bring Back</button>
<h2>The Killers</h2>
<script>
    var el = document.querySelector("h1");
    var fade = document.getElementById("fade");
    var show = document.getElementById("show");
    var fader = function () {
        el.style.opacity = 1;
        var timer = setInterval(function (){
            el.style.opacity -= 0.1;
            if (el.style.opacity == 0) {
                clearInterval(timer);
            }
        }, 40);
    }
    var shower = function () {
        el.style.opacity = 0;
        var timer = setInterval(function (){
            el.style.opacity += 0.1;
            if (el.style.opacity == 1) {
                clearInterval(timer);
            }
        }, 40);
    }
    fade.onclick = fader;
    show.onclick = shower;
</script>
</body>
</html>

3 个答案:

答案 0 :(得分:2)

这是由于浮点运算的行为。这解释了in this question。不透明度实际上从未达到0,因此定时器永远不会被清除。

解决方法是在执行减法和加法时使用toFixed(1)

var timer = setInterval(function (){
        el.style.opacity = (el.style.opacity - 0.1).toFixed(1);
        if (el.style.opacity == 0) {
            clearInterval(timer);
        }
    }, 40);

JSfiddle示例在这里:http://jsfiddle.net/28XNK/2/

答案 1 :(得分:2)

有一些因素促成了这一点:

  1. el.style.opacity始终为String,因此+=会连接而不是添加。将不透明度保持在单独的变量中,使其保持为Number

  2. 关于== 1== 0的数字aren't so precise正好在最后。请改用>= 1<= 0


  3. var fader = function () {
        var opacity = 1;
        el.style.opacity = opacity;
        var timer = setInterval(function () {
            opacity -= 0.1;
            el.style.opacity = Math.max(opacity, 0);
            if (opacity <= 0) {
                clearInterval(timer);
            }
        }, 40);
    }
    

    http://jsfiddle.net/qBgJY/

答案 2 :(得分:1)

opacity是一个字符串属性,因此您需要将其转换为float以对其进行修改:

el.style.opacity = parseFloat(el.style.opacity) + 0.1;