如何用原生JavaScript实现图片切换的淡入淡出过渡效果?
手风琴图片平滑淡入淡出过渡的实现方案
直接修改<img>的src属性没法触发CSS过渡——浏览器会直接替换图片资源,transition对src属性不生效。给你两个靠谱的实现办法:
方法1:双图片叠加切换(推荐)
用一个容器包裹两张图片,通过控制透明度实现淡入淡出,还能避免切换时的加载延迟。
1. 调整HTML结构
把单个<img>改成带两张图的容器:
<!-- 手风琴顶部图片容器 --> <div class="accordion-image-container"> <img id="image-default" src="默认图片URL" alt="默认图"> <img id="image-expanded" src="展开状态图片URL" alt="展开图"> </div> <!-- 手风琴按钮 --> <button id="button">切换手风琴</button> <!-- 手风琴内容 --> <div class="accordion-content">描述内容...</div>
2. 添加CSS样式
让两张图重叠,设置过渡效果:
.accordion-image-container { position: relative; width: 300px; /* 按需求调整宽度 */ height: 200px; /* 按需求调整高度 */ overflow: hidden; } .accordion-image-container img { position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover; /* 保持图片比例不变形 */ transition: opacity 0.4s ease-in-out; /* 过渡时长可自行调整,比如0.3s */ } #image-expanded { opacity: 0; pointer-events: none; /* 防止遮挡下方的默认图 */ } /* 手风琴展开时的图片状态 */ .accordion-expanded #image-default { opacity: 0; } .accordion-expanded #image-expanded { opacity: 1; pointer-events: auto; }
3. 修改JavaScript逻辑
把手风琴的展开/收起状态和图片切换绑定:
const button = document.querySelector("#button"); const imageContainer = document.querySelector(".accordion-image-container"); const accordionContent = document.querySelector(".accordion-content"); button.addEventListener("click", function () { // 切换图片容器的类,触发CSS过渡 imageContainer.classList.toggle("accordion-expanded"); // 同时切换手风琴内容的显示/隐藏(假设用hidden类控制) accordionContent.classList.toggle("hidden"); // 可选:提前加载第二张图,避免首次切换时加载缓慢 const expandedImg = document.querySelector("#image-expanded"); if (!expandedImg.complete) { expandedImg.loading = "eager"; } });
方法2:单图片+预加载+透明度过渡
不想修改HTML结构的话,可以用这个方案:先预加载两张图片,点击时先让当前图透明,更换src后再恢复透明度。
1. 添加CSS样式
给图片加上过渡属性:
#firstimage { transition: opacity 0.4s ease-in-out; }
2. 修改JavaScript逻辑
// 预加载两张图片,避免切换时的加载延迟 const img1 = new Image(); img1.src = "默认图片URL"; const img2 = new Image(); img2.src = "展开状态图片URL"; let isExpanded = false; // 记录手风琴的展开/收起状态 const button = document.querySelector("#button"); const image = document.querySelector("#firstimage"); button.addEventListener("click", function () { // 先让当前图片淡出 image.style.opacity = "0"; // 等待过渡完成后切换图片(时长要和CSS中的transition一致) setTimeout(() => { isExpanded = !isExpanded; image.src = isExpanded ? img2.src : img1.src; // 图片加载完成后淡入 image.onload = function() { image.style.opacity = "1"; }; }, 400); // 同时切换手风琴内容的显示/隐藏 const accordionContent = document.querySelector(".accordion-content"); accordionContent.classList.toggle("hidden"); });
关键注意点
- 必须预加载图片:不预加载的话,首次切换会出现图片加载缓慢的问题,导致过渡效果失效。
- 过渡要作用在
opacity这类可动画的CSS属性上,src属性无法触发过渡效果。 - 不要用原来的counter逻辑,直接把手风琴的展开状态和图片切换绑定,逻辑更清晰不易出错。
内容的提问来源于stack exchange,提问作者Ilaria Vilardi
相关产品推荐
相关产品推荐

