You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过切换按钮实现图片的平滑过渡效果?

问题描述

我用CSS transition 属性实现了页面元素的平滑切换,其他元素都正常生效,但图片切换部分没法实现平滑过渡。我目前是通过JavaScript修改display属性,切换id为lights-off和lights-on的两张图片的显示状态,相关代码如下:

var lightsOff = document.querySelector("#lights-off");
var lightsOn = document.querySelector("#lights-on");
lightsOff.style.display = "block";
lightsOn.style.display = "none";

切换回来的代码:

var lightsOff = document.querySelector("#lights-off");
var lightsOn = document.querySelector("#lights-on");
lightsOff.style.display = "none";
lightsOn.style.display = "block";

完整代码如下:

JavaScript

function myFunction() {
  var elements = document.querySelectorAll(".one, .three, .five");
  elements.forEach(function(element) {
    element.classList.toggle("dark-mode");
    if (element.classList.contains("dark-mode")) {
      if (element.classList.contains("one")) {
        var logoElement = element.querySelector('.logo');
        var h2Element = element.querySelector('h2');
        var sloganElement = element.querySelector('.slogan');
        logoElement.style.setProperty('color', 'white');
        sloganElement.style.setProperty('color', 'white');
        h2Element.style.setProperty('color', 'white');
      } else if (element.classList.contains("three")) {
        var textThreeOne = element.querySelector('.text-threeone');
        var textThreeTwo = element.querySelector('.text-threetwo');
        var p = element.querySelector('.text-threetwo + p');
        textThreeOne.style.setProperty('color', 'white');
        textThreeTwo.style.setProperty('color', 'white');
        p.style.setProperty('color', 'white');

        var lightsOff = document.querySelector("#lights-off");
        var lightsOn = document.querySelector("#lights-on");
        lightsOff.style.display = "block";
        lightsOn.style.display = "none";

        var blackmoon = document.querySelector(".moon");
        blackmoon.style.display = "block";
      } else if (element.classList.contains("five")) {
        var inputs = element.querySelectorAll('input');
        var textarea = element.querySelector('textarea');
        var submitBtn = element.querySelector('input[type="submit"]');
        inputs.forEach(input => {
          input.style.setProperty('background-color', '#1f1f1f');
          input.style.setProperty('color', '#ffffff');
        });
        textarea.style.setProperty('background-color', '#1f1f1f');
        textarea.style.setProperty('color', '#ffffff');
        submitBtn.style.setProperty('background-color', '#1f1f1f');
        // 鼠标悬停颜色
        submitBtn.style.setProperty('transition', 'background-color 0.2s');
        submitBtn.addEventListener("mouseover", function() {
          submitBtn.style.setProperty('background-color', '#101010');
        });
        submitBtn.addEventListener("mouseout", function() {
          submitBtn.style.setProperty('background-color', '#1f1f1f');
        });
        var contact = element.querySelector('#contact');
        var pOne = element.querySelector('.five>p+p');
        var pTwo = element.querySelector('.five>p+p+p');
        contact.style.setProperty('color', 'white');
        pOne.style.setProperty('color', 'white');
        pTwo.style.setProperty('color', 'white');
      } else {
        element.style.setProperty('color', 'white');
      }
    } else {
      if (element.classList.contains("one")) {
        var logoElement = element.querySelector('.logo');
        logoElement.style.setProperty('color', '#353535');
        var sloganElement = element.querySelector('.slogan');
        sloganElement.style.setProperty('color', '#353535');
        var sloganElement = element.querySelector('h2');
        sloganElement.style.setProperty('color', '#353535');

        var blackmoon = document.querySelector(".moon");
        blackmoon.style.display = "none";
      } else if (element.classList.contains("three")) {
        var textThreeOne = element.querySelector('.text-threeone');
        var textThreeTwo = element.querySelector('.text-threetwo');
        var p = element.querySelector('.text-threetwo + p');
        var lightsOff = document.querySelector("#lights-off");
        var lightsOn = document.querySelector("#lights-on");
        lightsOff.style.display = "none";
        lightsOn.style.display = "block";

        p.style.setProperty('color', '#353535');
        textThreeOne.style.setProperty('color', '#353535');
        textThreeTwo.style.setProperty('color', '#353535');
      } else if (element.classList.contains("five")) {
        var inputs = element.querySelectorAll('input');
        var textarea = element.querySelector('textarea');
        var submitBtn = element.querySelector('input[type="submit"]');
        inputs.forEach(input => {
          input.style.setProperty('background-color', '#efefef');
          input.style.setProperty('color', 'black');

        });
        textarea.style.setProperty('background-color', '#efefef');
        textarea.style.setProperty('color', 'black');

        submitBtn.style.setProperty('background-color', '#437bff');
        submitBtn.style.setProperty('color', 'white');

        // 鼠标悬停颜色
        submitBtn.style.setProperty('transition', 'background-color 0.2s');
        submitBtn.addEventListener("mouseover", function() {
          submitBtn.style.setProperty('background-color', '#133edb');
        });
        submitBtn.addEventListener("mouseout", function() {
          submitBtn.style.setProperty('background-color', '#437bff');
        });

        var contact = element.querySelector('#contact');
        var pOne = element.querySelector('.five>p+p');
        var pTwo = element.querySelector('.five>p+p+p');
        contact.style.setProperty('color', '#353535');
        pOne.style.setProperty('color', '#353535');
        pTwo.style.setProperty('color', '#353535');
      }
    }
  });
}

CSS

.one,
.three,
.five {
  transition: 1500ms;
}

HTML

<div>
  <button class="darkmodebtn" onclick="myFunction()"></button>
  <img id="lights-off" src="../images/darkmode.png" style="display: none;">
  <img id="lights-on" src="../images/ABC.png">
</div>

请问怎么修改才能实现图片的平滑过渡?


解决方案

问题根源是display属性属于离散状态属性,CSS transition无法对其变化生成过渡动画。要实现图片平滑切换,需要改用**透明度(opacity)和可见性(visibility)**属性,配合绝对定位让两张图片重叠,通过类切换控制过渡效果。

步骤1:调整HTML结构与基础CSS

给图片添加容器并设置定位,让两张图片重叠:

<div class="light-container">
  <button class="darkmodebtn" onclick="myFunction()"></button>
  <img id="lights-off" src="../images/darkmode.png" class="light-img">
  <img id="lights-on" src="../images/ABC.png" class="light-img active">
</div>

添加对应的CSS规则:

.light-container {
  position: relative; /* 作为图片的定位容器 */
}

.light-img {
  position: absolute; /* 让两张图片完全重叠 */
  top: 0;
  left: 0;
  transition: opacity 1.5s ease, visibility 1.5s ease; /* 对透明度和可见性设置过渡 */
  visibility: hidden;
  opacity: 0;
}

.light-img.active {
  visibility: visible; /* 激活状态下可见 */
  opacity: 1; /* 激活状态下完全不透明 */
}

.one,
.three,
.five {
  transition: 1500ms;
}

步骤2:修改JavaScript逻辑

不再操作display属性,改为切换active类来控制图片显示:

// 深色模式激活时(three元素分支)
var lightsOff = document.querySelector("#lights-off");
var lightsOn = document.querySelector("#lights-on");
lightsOff.classList.add('active');
lightsOn.classList.remove('active');

// 深色模式关闭时(three元素分支)
var lightsOff = document.querySelector("#lights-off");
var lightsOn = document.querySelector("#lights-on");
lightsOff.classList.remove('active');
lightsOn.classList.add('active');

额外优化建议

  1. 尽量用CSS类管理状态,避免直接操作元素内联样式——比如把深色模式的文本颜色、输入框样式都写成独立的CSS类,通过toggle方法切换,代码更简洁易维护。
  2. 如果两张图片尺寸不同,给.light-img设置固定宽高,避免切换时出现布局跳动。

内容的提问来源于stack exchange,提问作者andre

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 06:20:27