为什么我的 HTML 图片不会褪色

Why won't my HTML Images fade

我正在尝试创建一个简单的幻灯片效果。我有 10 张图片,我创建了一个基本的 HTML 页面,其中有 2 个按钮可以转到右边或左边的图片。单击按钮时,图像会发生变化。

现在,我正在尝试为不断变化的图像添加基本的淡入淡出功能。但是没有显示淡入淡出效果。当我发出警报时,我注意到淡入淡出正在发生,但没有警报它太快以至于看不到。此外,它发生在上一张图片上,而不是下一张图片上。

    <html>
<head>
    <style>
        .main {
            text-align: center;
        }
        .centered {
            display: inline-block;
        }
        #image {
            border: solid 2px;
            width: 500px;
            height: 500px;
        }
        #number {
            font-size: 30px;
        }
    </style>
    <script>
        function goLeft() {
            var image = document.getElementById("image");
            var pos = document.getElementById("number");
            if(Number(pos.innerHTML)==1) {
                image.src = "Images\10.jpg"
                pos.innerHTML = 10;
            } else {
                image.src = "Images\" + (Number(pos.innerHTML)-1).toString() + ".jpg"
                pos.innerHTML = (Number(pos.innerHTML)-1).toString();
            }
            for (var i=0; i<25; i++) {
                setTimeout(changeOpacity(image, i), 1000);
            }
        }

        function changeOpacity(image, i) {
            alert(parseFloat(i*4/100).toString());
            image.style.opacity = (parseFloat(i*4/100).toString()).toString();
        }

        function goRight() {
            var image = document.getElementById("image");
            var pos = document.getElementById("number");
            if(Number(pos.innerHTML)==10) {
                image.src = "Images\1.jpg"
                pos.innerHTML = 1;
            } else {
                image.src = "Images\" + (Number(pos.innerHTML)+1).toString() + ".jpg"
                pos.innerHTML = (Number(pos.innerHTML)+1).toString();
            }
            for (var i=0; i<25; i++) {
                setTimeout(changeOpacity(image, i), 1000);
            }
        }
    </script>
</head>
<body>
    <div class="main">
        <div class="centered">
            <img id="image" src="Images.jpg">
        </div>
    </div>
    <div class="main">
        <div class="centered">
            <span id="number">1</span>
        </div>
    </div>
    <div class="main">
        <div class="centered">
            <button onclick="goLeft()" style="margin-right:50px;">Go Left</button>
            <button onclick="goRight()" style="margin-left:50px;">Go Right</button>
        </div>
    </div>
</body>

为什么要使用纯 JavaScript? 使用 jQuery. 它有一个非常简洁的 fadeTo() 函数和一个有用的 fadeIn() 函数。

可能想用那个 ;)

问题在于您的 goLeft 方法和 goRight 方法中的这段代码:

for (var i=0; i<25; i++) {
    setTimeout(changeOpacity(image, i), 1000);
}

您正在创建 25 个计时器,每个计时器将在大约 1 秒后执行。

创建动画最好留给 CSS。

在你的 CSS 添加:

#image {
    transition: opacity 0.5s ease;
}

然后在您的 JavaScript 中,只需:image.style.opacity = 1.0;

当不透明度发生变化时,CSS 将以 css 中定义的速度自动转换不透明度长度,例如 0.5s。随意尝试。

我还在这里添加了一个jsfiddle:http://jsfiddle.net/dya7L8wq/

您误解了 setTimeoutfor 循环。

Norman 的回答为 CSS 提供了一个很好的解决方案,但他并没有过多地谈论为什么您的代码无法正常工作。所以我想解释一下。

for (var i=0; i<25; i++) {
    setTimeout(changeOpacity(image, i), 1000);
}

你的假设是:

  1. 1 秒后调用 changeOpacity(image, 0)
  2. 调用 changeOpacity(image, 1) 1 秒 在第 1 步之后
  3. 调用 changeOpacity(image, 2) 1 秒 在第 2 步之后
  4. 调用 changeOpacity(image, 3) 1 秒 在第 3 步之后 ....

最后一步是在上一步之后调用 changeOpacity(image, 24) 1 秒。

实际情况是:

循环几乎立即完成!

在每次迭代中,setTimeout 将一个 异步 函数调用排队,然后就完成了!也就是说,它将立即 return,而不是等到 changeOpacity returns.

然后,大约 1 秒后,changeOpacity 几乎同时触发 25 次,因为你在 for 循环中排队了 25 次。

这里的另一个问题是:在changeOpacity调用中,传入的参数i不是123.... ,它们都具有导致 for 循环退出(1 秒前)的相同值 - 25,因为 JS 在之前没有块作用域ES6(在 ES6 中我们有关键字 let)。


在纯 JS 解决方案中,为了确保时间顺序,我们通常会在每一步结束时排队下一次调用:

function changeOpacity() {
    // do something here
    // before the function returns, set up a future invocation
    setTimeout(changeOpacity, 1000)
}

这是一个打印从 1 到 5 的数字列表的示例:

var go = document.getElementById('go')
var op = document.getElementById('output')
var i = 0

function printNum() {
  var p = document.createElement('p')
  p.innerHTML = ++i
  op.appendChild(p)
  
  // next step
  if(i < 5) {
    setTimeout(printNum, 500)
  }
}

go.onclick = printNum
<button id="go">GO</button>
<div id="output"></div>