javascript中的淡入淡出

Hak*_*kan 5 javascript function settimeout fadeout fadein

我继续工作:https://codereview.stackexchange.com/questions/7315/fade-in-and-fade-out-in-pure-javascript

在设置新功能之前检测淡入或淡出是否完成的最佳方法是什么。这是我的方法,但我想还有更好的方法吗?

我添加了警报,以便您更容易看到。

我为什么要这样做是因为:如果在 for 循环完成之前按下按钮,动画看起来会很糟糕。

我希望按钮仅在淡入淡出完成时才起作用。

<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
</head>

<body>
        <div>
        <span id="fade_in">Fade In</span> | 
        <span id="fade_out">Fade Out</span></div>
        <div id="fading_div" style="display:none;height:100px;background:#f00">Fading Box</div>
    </div>
</div>

<script type="text/javascript">
var done_or_not = 'done';

// fade in function
function function_opacity(opacity_value, fade_in_or_fade_out) { // fade_in_or_out - 0 = fade in, 1 = fade out
    document.getElementById('fading_div').style.opacity = opacity_value / 100;
    document.getElementById('fading_div').style.filter = 'alpha(opacity='+opacity_value+')';
    if(fade_in_or_fade_out == 1 && opacity_value == 1)
    {
        document.getElementById('fading_div').style.display = 'none';
        done_or_not = 'done';
        alert(done_or_not);
    }
    if(fade_in_or_fade_out == 0 && opacity_value == 100)
    {
        done_or_not = 'done';
        alert(done_or_not);
    }

}





window.onload =function(){

// fade in click
document.getElementById('fade_in').onclick = function fadeIn() {
    document.getElementById('fading_div').style.display='block';
    var timer = 0;
    if (done_or_not == 'done')
    {
        for (var i=1; i<=100; i++) {
            set_timeout_in = setTimeout("function_opacity("+i+",0)", timer * 10);
            timer++;
            done_or_not = 'not_done'
        }
    }
};

// fade out click
document.getElementById('fade_out').onclick = function fadeOut() {
    clearTimeout(set_timeout_in);
    var timer = 0;
    if (done_or_not == 'done')
    {
        for (var i=100; i>=1; i--) {
            set_timeout_out = setTimeout("function_opacity("+i+",1)", timer * 10);
            timer++;
            done_or_not = 'not_done'
        }
    }
};



}// END window.onload
</script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

PPv*_*PvG 4

我同意一些评论。有许多不错的 JavaScript 库,它们不仅使编写代码变得更容易,而且还可以解决一些浏览器兼容性问题。

话虽如此,您可以修改淡入淡出函数以接受回调:

function fadeIn(callback) {
    return function() {
        function step() {
            // Perform one step of the animation

            if (/* test whether animation is done*/) {
                callback();   // <-- call the callback
            } else {
                setTimeout(step, 10);
            }
        }
        setTimeout(step, 0); // <-- begin the animation
    };
}

document.getElementById('fade_in').onclick = fadeIn(function() {
    alert("Done.");
});
Run Code Online (Sandbox Code Playgroud)

这样,fadeIn将返回一个函数。该函数将用作处理程序onclick。您可以传递fadeIn一个函数,该函数将在执行动画的最后一步后调用。内部函数(由 返回的函数fadeIn)仍然可以访问callback,因为 JavaScript 在它周围创建了一个闭包

您的动画代码仍然需要大量改进,但这就是大多数 JavaScript 库所做的:

  • 分步执行动画;
  • 测试一下是否完成;
  • 最后一步后调用用户的回调。

最后要记住的一件事:动画可能会变得非常复杂。例如,如果您想要一种可靠的方法来确定动画的持续时间,您将需要使用补间函数(也是大多数库所做的)。如果数学不是你的强项,这可能不会那么令人愉快......


针对您的评论:您说您希望它继续以同样的方式工作;“如果函数很忙,就不会发生任何事情。”

所以,如果我理解正确的话,你希望动画被阻止。其实我可以告诉你两件事:

  1. 您的动画不会阻塞(至少动画本身不会阻塞——请阅读下文)。
  2. 您仍然可以使用任何类型的异步动画使其按照您想要的方式工作。

这就是你正在使用的done_or_not用途。事实上,这是一种常见的模式。通常使用布尔值 (truefalse) 代替字符串,但原理始终相同:

// Before anything else:
var done = false;

// Define a callback:
function myCallback() {
    done = true;
    // Do something else
}

// Perform the asynchronous action (e.g. animations):
done = false;
doSomething(myCallback);
Run Code Online (Sandbox Code Playgroud)

我仅使用 jQuery 创建了一个您想要执行的动画类型的简单示例。您可以在这里查看: http: //jsfiddle.net/PPvG/k73hU/

var buttonFadeIn = $('#fade_in');
var buttonFadeOut = $('#fade_out');
var fadingDiv = $('#fading_div');

var done = true;

buttonFadeIn.click(function() {
    if (done) {
        // Set done to false:
        done = false;

        // Start the animation:
        fadingDiv.fadeIn(
            1500, // <- 1500 ms = 1.5 second
            function() {
                // When the animation is finished, set done to true again:
                done = true;
            }
        );
    }
});

buttonFadeOut.click(function() {
    // Same as above, but using 'fadeOut'.
});
Run Code Online (Sandbox Code Playgroud)

因为done变量,按钮仅在动画完成时才会响应。正如您所看到的,代码非常简短且可读。这就是使用 jQuery 这样的库的好处。当然,您可以自由地构建自己的解决方案。

关于性能:大多数 JS 库使用补间来执行动画,这通常比固定步骤性能更高。对于用户来说,它看起来肯定更平滑,因为位置取决于已经过去的时间,而不是已经过去的步数。

我希望这有帮助。:-)