简体   繁体   English

JS淡入淡出效果不起作用(for循环)

[英]A JS fade effect doesn't work (for loop)

I tried doing a JS fade effect with the setTimeout() function and it appeared to work to some extent, but I can't seem to figure out what's wrong with the code below: 我尝试用setTimeout()函数做一个JS淡入淡出效果,它似乎在某种程度上起作用,但我似乎无法弄清楚下面的代码有什么问题:

<html>
<head>
<title></title>
<script type="text/javascript">
function FadeEffect(n)
{
    var i=1;
    fade = document.getElementById("box");
    if (n===1)
    {
        fade.style.opacity=i/10;
        i++;
        setTimeout("FadeEffect(1)",50);
        if (fade.style.opacity=1)
        {
         var i=1;
        }
    }
    else if (n===0)
    {
        fade.style.opacity=1-i/10;
        i++;
        setTimeout("FadeEffect(0)",50);
        if (fade.style.opacity=0)
        {
        var i=1;
        }
    }
}


</script>
<style type="text/css">
#box{
width: 200px;
height: 50px;
border: 1px solid black;
background-color: #ccc;
opacity: 0;
}
</style>
</head>
<body>
<div onMouseOver="FadeEffect(1)" onMouseOut="FadeEffect(0)" id="box">Menu</div>
</body>
</html>

Edit: updated the code with setTimeout() functions. 编辑:使用setTimeout()函数更新代码。

The problem is that all those changes to the style will happen before the browser bothers to update the display. 问题是所有这些样式的更改都会在浏览器无法更新显示之前发生。 What you need to do is space out the changes over a much, much longer period of time using "setTimeout()". 您需要做的是使用“setTimeout()”在更长的时间内完成更改。

function fadeIn() {
  function increment() {
    box.style.opacity = Math.min(1.0, (opacity += 0.1));
    if (opacity < 1.0) {
      setTimeout(increment, 100);
    }
  }
  var box = document.getElementById('box'), opacity = 0;
  box.style.opacity = opacity;
  setTimeout(increment, 100);
}

editHere is a jsfiddle to demonstrate. 编辑 - 是一个jsfiddle来演示。

There are two problems with the function that I can see. 我能看到的功能有两个问题。

First, your if statements both do an assignment rather than a comparison. 首先,你的if语句既可以进行赋值,也可以进行比较。 You are saying if (n=0) (one =, assignment) when you should be saying if (n===0) (three ===, comparison, or you can use two == for a type-converting comparison). 你是说if (n=0) (one =,赋值)当你应该说if (n===0) (三个===,比较,或者你可以使用两个==进行类型转换比较) 。

Second, using a for loop to repeatedly change the style isn't going to fade because the browser doesn't update the display at the same time as your code is executing - essentially it uses the same thread for display and for JavaScript. 其次,使用for循环重复更改样式不会消失,因为浏览器不会在代码执行的同时更新显示 - 实质上它使用相同的线程进行显示和JavaScript。 So the page will be updated after the function exits. 因此在退出函数后页面将会更新。 You need to give the browser a chance to update after each iteration by using setTimeout() - something like: 您需要通过使用setTimeout()为浏览器提供在每次迭代后更新的机会 - 类似于:

function fadeEffect(element,startValue,target,delay){
   element.style.opacity = startValue;
   if (startValue < target)
      startValue = Math.min(startValue + 0.1, target);
   else
      startValue = Math.max(startValue - 0.1, target);

   if (startValue != target)
      setTimeout(function(){fadeEffect(element,startValue,target,delay);}, delay);
}

<div onMouseOver="fadeEffect(this, 1, 0, 100);"
     onMouseOut="fadeEffect(this, 0, 1, 100);" id="box">Menu</div>

Demo: http://jsfiddle.net/hLQ6y/2/ 演示: http//jsfiddle.net/hLQ6y/2/

EDIT: Note that this code doesn't cope all that brilliantly if you move the mouse in and out too quickly, ie, if you trigger the fade in before the fade out has finished. 编辑:请注意,如果您将鼠标移入和移出太快,即如果在淡出完成之前触发淡入,则此代码无法很好地应对。 (You can see what I mean in my jsfiddle.) You can solve this by saving the return from .setTimeout() and calling .clearTimeout() if required. (你可以在我的jsfiddle中看到我的意思。)你可以通过从.setTimeout()保存返回并在需要时调用.clearTimeout()来解决这个问题。 Given that I've already covered the essence of the question I'll leave the fine-tuning as an exercise for the reader... 鉴于我已经涵盖了问题的本质,我将微调作为读者的练习......

UPDATE: Your updated code has introduced new if statements with the same assignment-instead-of-comparison problem. 更新:您的更新代码引入了具有相同赋值 - 替代比较问题的新if语句。 Also it is calling setTimeout() forever - you should do that conditionally as in the answers Pointy and I gave. 它也是永远调用setTimeout() - 你应该像在Pointy和我给的答案中那样有条件地做。 Also you seem to be relying on the variable i which, as a local variable, will not retain its value between calls - you could make it a global, but better to manage it as a parameter like I did or as a local variable in an outer function like Pointy did. 此外,您似乎依赖于变量i ,作为局部变量,它不会在调用之间保留其值 - 您可以使其成为全局变量,但最好将其作为参数管理,就像我做的那样或作为局部变量管理它像Pointy那样的外在功能。

If you want it to fade, you need to create a function that sets the opacity -0.1 or +0.1 and then calls itself with setTimeout in 100ms (or fewer). 如果你想让它淡出,你需要创建一个设置不透明度-0.1或+0.1的函数,然后用100ms(或更少)的setTimeout调用自身。 If you don't let the script wait, it will be too fast and immediately set the opacity to 1.0. 如果你不让脚本等待,它会太快并立即将不透明度设置为1.0。

Anyways, you could do this a lot easier using jQuery. 无论如何,使用jQuery可以更轻松地完成这项工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM