修复轮播图右入
All checks were successful
Gitea Actions Official-website / deploy-dev (push) Successful in 3s
All checks were successful
Gitea Actions Official-website / deploy-dev (push) Successful in 3s
This commit is contained in:
@@ -66,18 +66,18 @@
|
||||
{else/}
|
||||
<div class="swiper-wrapper">
|
||||
{volist name="data.top_focus_images" id="tfi"}
|
||||
<div class="swiper-container-texts" style="color:#fff">
|
||||
<div class="swiper-container-texts-t">{$tfi.title}</div>
|
||||
<div class="swiper-container-texts-p">{$tfi.desc||raw|htmlspecialchars_decode}</div>
|
||||
<div class="swiper-container-texts-img">
|
||||
<a href="{$tfi.link}">
|
||||
<img src="__IMAGES__/topic_laptop/ljgd.png" alt="">
|
||||
</a>
|
||||
<div class="swiper-slide auto-swiper-slide">
|
||||
<div class="swiper-container-texts" style="color:#fff">
|
||||
<div class="swiper-container-texts-t">{$tfi.title}</div>
|
||||
<div class="swiper-container-texts-p">{$tfi.desc||raw|htmlspecialchars_decode}</div>
|
||||
<div class="swiper-container-texts-img">
|
||||
<a href="{$tfi.link}">
|
||||
<img src="__IMAGES__/topic_laptop/ljgd.png" alt="" loading="lazy" >
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<img src="{$tfi.image}" alt="{$tfi.title}" loading="lazy" />
|
||||
</div>
|
||||
<a class="swiper-slide auto-swiper-slide">
|
||||
<img src="{$tfi.image}" alt="{$tfi.title}" />
|
||||
</a>
|
||||
{/volist}
|
||||
</div>
|
||||
{/eq}
|
||||
@@ -87,35 +87,35 @@
|
||||
<div class="amd-box">
|
||||
<div class="amd-img-box">
|
||||
<div class="amd-img-1 opacity0" data-order="1" data-name="">
|
||||
{notempty name="data.perf.0"}<img src="{$data.perf.0.image}" alt="{$data.perf.0.title}" class="amd-img-1-1">{/notempty}
|
||||
{notempty name="data.perf.0"}<img src="{$data.perf.0.image}" alt="{$data.perf.0.title}" class="amd-img-1-1" loading="lazy" >{/notempty}
|
||||
</div>
|
||||
<div class="amd-img-2 opacity0" data-order="2" data-name="">
|
||||
<div class="amd-img-2-1">{notempty name="data.perf.1"}<img src="{$data.perf.1.image}" alt="{$data.perf.1.title}">{/notempty}</div>
|
||||
<div class="amd-img-2-2">{notempty name="data.perf.2"}<img src="{$data.perf.2.image}" alt="{$data.perf.2.title}">{/notempty}</div>
|
||||
<div class="amd-img-2-1">{notempty name="data.perf.1"}<img src="{$data.perf.1.image}" alt="{$data.perf.1.title}" loading="lazy" >{/notempty}</div>
|
||||
<div class="amd-img-2-2">{notempty name="data.perf.2"}<img src="{$data.perf.2.image}" alt="{$data.perf.2.title}" loading="lazy" >{/notempty}</div>
|
||||
</div>
|
||||
<div class="amd-img-3 opacity0" data-order="3" data-name="">
|
||||
<div class="amd-img-3-left">
|
||||
{notempty name="data.perf.3"}<img src="{$data.perf.3.image}" alt="{$data.perf.3.title}" class="amd-img-3-1-left">{/notempty}
|
||||
{notempty name="data.perf.3"}<img src="{$data.perf.3.image}" alt="{$data.perf.3.title}" class="amd-img-3-1-left" loading="lazy" >{/notempty}
|
||||
</div>
|
||||
<div class="amd-img-3-right">
|
||||
<div class="amd-img-3-1-right">
|
||||
{notempty name="data.perf.4"}<img src="{$data.perf.4.image}" alt="{$data.perf.4.title}">{/notempty}
|
||||
{notempty name="data.perf.4"}<img src="{$data.perf.4.image}" alt="{$data.perf.4.title}" loading="lazy" >{/notempty}
|
||||
</div>
|
||||
<!-- {notempty name="data.perf.4"}<img src="{$data.perf.4.image}" alt="{$data.perf.4.title}">{/notempty} -->
|
||||
<div class="amd-img-3-2-right">
|
||||
{notempty name="data.perf.5"}<img src="{$data.perf.5.image}" alt="{$data.perf.5.title}">{/notempty}
|
||||
{notempty name="data.perf.5"}<img src="{$data.perf.5.image}" alt="{$data.perf.5.title}" loading="lazy" >{/notempty}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="amd-img-4 opacity0" data-order="4" data-name="">
|
||||
{notempty name="data.perf.6"}<img src="{$data.perf.6.image}" alt="{$data.perf.6.title}">{/notempty}
|
||||
{notempty name="data.perf.6"}<img src="{$data.perf.6.image}" alt="{$data.perf.6.title}" loading="lazy" >{/notempty}
|
||||
</div>
|
||||
<div class="amd-img-5 opacity0" data-order="5" data-name="">
|
||||
{notempty name="data.perf.7"}<img src="{$data.perf.7.image}" alt="{$data.perf.7.title}">{/notempty}
|
||||
{notempty name="data.perf.8"}<img src="{$data.perf.8.image}" alt="{$data.perf.8.title}">{/notempty}
|
||||
{notempty name="data.perf.7"}<img src="{$data.perf.7.image}" alt="{$data.perf.7.title}" loading="lazy" >{/notempty}
|
||||
{notempty name="data.perf.8"}<img src="{$data.perf.8.image}" alt="{$data.perf.8.title}" loading="lazy" >{/notempty}
|
||||
</div>
|
||||
<div class="amd-img-6 opacity0" data-order="6" data-name="">
|
||||
{notempty name="data.perf.9"}<img src="{$data.perf.9.image}" alt="{$data.perf.9.title}">{/notempty}
|
||||
{notempty name="data.perf.9"}<img src="{$data.perf.9.image}" alt="{$data.perf.9.title}" loading="lazy" >{/notempty}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -129,7 +129,7 @@
|
||||
</div>
|
||||
<div class="float-cards opacity0" data-order="8" >
|
||||
{volist name="data.cpu" id="co"}
|
||||
<img class="float-card" src="{$co.image}" alt="{$co.title}">
|
||||
<img class="float-card" src="{$co.image}" alt="{$co.title}" loading="lazy" >
|
||||
{/volist}
|
||||
</div>
|
||||
</div>
|
||||
@@ -206,19 +206,19 @@
|
||||
{eq name=":cookie('think_lang')" value="en-us"}
|
||||
<div class="readon-js1">{$gpu_first_section.short_title|default=''|raw}</div>
|
||||
<div class="readon-img1 opacity0" data-order="10">
|
||||
<img src="{$gpu_first_section.extra_image|default=''}" alt="">
|
||||
<img src="{$gpu_first_section.extra_image|default=''}" alt="" loading="lazy" >
|
||||
</div>
|
||||
{else/}
|
||||
<div class="readon-js">{$gpu_first_section.short_title|default=''|raw}</div>
|
||||
<div class="readon-img opacity0" data-order="10">
|
||||
<img src="{$gpu_first_section.extra_image|default=''}" alt="">
|
||||
<img src="{$gpu_first_section.extra_image|default=''}" alt="" loading="lazy" >
|
||||
</div>
|
||||
{/eq}
|
||||
|
||||
</div>
|
||||
<div class="readon-img-box opacity0" data-order="11">
|
||||
{volist name="data.gpu" id="go"}
|
||||
<img src="{$go.image}" alt="">
|
||||
<img src="{$go.image}" alt="" loading="lazy" >
|
||||
{/volist}
|
||||
</div>
|
||||
</div>
|
||||
@@ -305,7 +305,7 @@
|
||||
{/eq}
|
||||
<div class="m2-img-box opacity0" data-order="16">
|
||||
{volist name="data.hard_drive" id="ho"}
|
||||
<img src="{$ho.image}" alt="">
|
||||
<img src="{$ho.image}" alt="" loading="lazy" >
|
||||
{/volist}
|
||||
</div>
|
||||
</div>
|
||||
@@ -322,7 +322,7 @@
|
||||
{/notempty}
|
||||
<div class="fs-box">
|
||||
{notempty name="data.cooling_system.0"}
|
||||
<img src="{$data.cooling_system.0.image|default=''}" alt="" class="fs-img">
|
||||
<img src="{$data.cooling_system.0.image|default=''}" alt="" class="fs-img" loading="lazy" >
|
||||
<video
|
||||
src="{$data.cooling_system.0.video|default=''}"
|
||||
class="fs-video" muted loop playsinline autoplay
|
||||
@@ -334,11 +334,11 @@
|
||||
{/notempty}
|
||||
<div class="fs-box-img opacity0" data-order="18">
|
||||
<div class="fs-h-img">
|
||||
{notempty name="data.cooling_system.1"}<img src="{$data.cooling_system.1.image}" alt="">{/notempty}
|
||||
{notempty name="data.cooling_system.2"}<img src="{$data.cooling_system.2.image}" alt="">{/notempty}
|
||||
{notempty name="data.cooling_system.1"}<img src="{$data.cooling_system.1.image}" alt="" loading="lazy" >{/notempty}
|
||||
{notempty name="data.cooling_system.2"}<img src="{$data.cooling_system.2.image}" alt="" loading="lazy" >{/notempty}
|
||||
</div>
|
||||
<div class="fs-b-img" style="min-height: 20px;">
|
||||
{notempty name="data.cooling_system.3"}<img src="{$data.cooling_system.3.image}" alt="">{/notempty}
|
||||
{notempty name="data.cooling_system.3"}<img src="{$data.cooling_system.3.image}" alt="" loading="lazy" >{/notempty}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -368,13 +368,13 @@
|
||||
{eq name=":cookie('think_lang')" value="en-us"}
|
||||
<div class="ips-img1 opacity0" data-order="21">
|
||||
{volist name="data.screen_soft_light" id="so"}
|
||||
<img src="{$so.image}" alt="">
|
||||
<img src="{$so.image}" alt="" loading="lazy" >
|
||||
{/volist}
|
||||
</div>
|
||||
{else/}
|
||||
<div class="ips-img opacity0" data-order="21">
|
||||
{volist name="data.screen_soft_light" id="so"}
|
||||
<img src="{$so.image}" alt="">
|
||||
<img src="{$so.image}" alt="" loading="lazy" >
|
||||
{/volist}
|
||||
</div>
|
||||
{/eq}
|
||||
@@ -394,7 +394,7 @@
|
||||
{/notempty}
|
||||
<div class="rgb-img opacity0" data-order="23">
|
||||
{volist name="data.screen_color_gamut" id="so"}
|
||||
<img src="{$so.image}" alt="">
|
||||
<img src="{$so.image}" alt="" loading="lazy" >
|
||||
{/volist}
|
||||
</div>
|
||||
</div>
|
||||
@@ -410,10 +410,10 @@
|
||||
{/notempty}
|
||||
<div class="beforeafter ba-slider">
|
||||
{assign name="anti_glare_left" value=":array_shift($data.screen_anti_glare)"/}
|
||||
<img src="{$anti_glare_left.image|default=''}">
|
||||
<img src="{$anti_glare_left.image|default=''}" loading="lazy" >
|
||||
<div class="resize">
|
||||
{assign name="anti_glare_right" value=":array_shift($data.screen_anti_glare)"/}
|
||||
<img src="{$anti_glare_right.image|default=''}">
|
||||
<img src="{$anti_glare_right.image|default=''}" loading="lazy" >
|
||||
</div>
|
||||
<span class="handle"></span>
|
||||
</div>
|
||||
@@ -429,7 +429,7 @@
|
||||
<div class="swiper-wrapper">
|
||||
{volist name="data.exterior_texture" id="eo"}
|
||||
<a class="swiper-slide auto-swiper-slide">
|
||||
<img src="{$eo.image}" alt="{$eo.title}" href="{$eo.link}">
|
||||
<img src="{$eo.image}" alt="{$eo.title}" href="{$eo.link}" loading="lazy" >
|
||||
</a>
|
||||
{/volist}
|
||||
</div>
|
||||
@@ -446,7 +446,7 @@
|
||||
</div>
|
||||
<div class="wift6-img opacity0" data-order="27">
|
||||
{volist name="data.network_card" id="no"}
|
||||
<img src="{$no.image}" alt="">
|
||||
<img src="{$no.image}" alt="" loading="lazy" >
|
||||
{/volist}
|
||||
</div>
|
||||
</div>
|
||||
@@ -460,7 +460,7 @@
|
||||
</div>
|
||||
<div class="xh-img opacity0" data-order="29">
|
||||
{volist name="data.battery_life" id="bo"}
|
||||
<img src="{$bo.image}" alt="">
|
||||
<img src="{$bo.image}" alt="" loading="lazy" >
|
||||
{/volist}
|
||||
</div>
|
||||
<div class="xh-b-p">{$battery_life_first.desc|default=''|raw}</div>
|
||||
@@ -472,7 +472,7 @@
|
||||
<p>{:lang_i18n("标配多种接口,会议室连接电脑、U盘传输文件、TF卡读取等,全都轻松搞定")}</p>
|
||||
</div>
|
||||
<div class="img-wrapper">
|
||||
<img src="__IMAGES__/topic_laptop/jk.png" alt="接口图" class="bg-img" id="bgImg">
|
||||
<img src="__IMAGES__/topic_laptop/jk.png" alt="接口图" class="bg-img" id="bgImg" loading="lazy" >
|
||||
</div>
|
||||
<div class="annotation anno-delay-1" style="top: 53.5%; left: 42%;"><span style="text-align: center;">{:lang_i18n('肯辛通锁孔')}</span></div>
|
||||
<div class="annotation anno-delay-1" style="top: 57%; left: 37%;"><span style="text-align: center;">{:lang_i18n('千兆网口')}</span></div>
|
||||
@@ -489,22 +489,22 @@
|
||||
<div class="lb">
|
||||
<div class="carousel-wrapper">
|
||||
<div class="carousel-arrow arrow-left">
|
||||
<img src="__IMAGES__/topic_laptop/l1.png" alt="左箭头">
|
||||
<img src="__IMAGES__/topic_laptop/l1.png" alt="左箭头" loading="lazy" >
|
||||
</div>
|
||||
<div class="carousel-container">
|
||||
<div class="carousel-imgs">
|
||||
{volist name="data.scene_focus_images" id="so"}
|
||||
<img src="{$so.image}" alt="{$so.title}" class="carousel-img">
|
||||
<img src="{$so.image}" alt="{$so.title}" class="carousel-img" >
|
||||
{/volist}
|
||||
</div>
|
||||
</div>
|
||||
<div class="carousel-arrow arrow-right">
|
||||
<img src="__IMAGES__/topic_laptop/r1.png" alt="右箭头">
|
||||
<img src="__IMAGES__/topic_laptop/r1.png" alt="右箭头" loading="lazy" >
|
||||
</div>
|
||||
</div>
|
||||
<div class="carousel-texts">
|
||||
{volist name="data.scene_focus_images" id="so"}
|
||||
<div class="carousel-text {if $key == 0}active{/if}" data-index="{$key}">
|
||||
<div class="carousel-text {if $key == 0}active{/if}" data-index="{$key}" loading="lazy" >
|
||||
{eq name=":cookie('think_lang')" value="en-us"}
|
||||
<div class="carousel-text-t1">{$so.title}</div>
|
||||
<div class="carousel-text-p1">{$so.short_title}</div>
|
||||
@@ -527,7 +527,7 @@
|
||||
{notempty name="camare_microphone"}
|
||||
<div class="tab-panel active">
|
||||
<div class="tab-panel-img">
|
||||
<img src="{$camare_microphone.image}" alt="{$camare_microphone.title}" class="content-image">
|
||||
<img src="{$camare_microphone.image}" alt="{$camare_microphone.title}" class="content-image" loading="lazy" >
|
||||
</div>
|
||||
</div>
|
||||
{/notempty}
|
||||
@@ -564,7 +564,7 @@
|
||||
<div class="bottom-img-box">
|
||||
<div class="bottom-img opacity0" data-order="31">
|
||||
{volist name="data.product_testing" id="po"}
|
||||
<img src="{$po.image}" alt="{$po.title}">
|
||||
<img src="{$po.image}" alt="{$po.title}" loading="lazy" >
|
||||
{/volist}
|
||||
</div>
|
||||
</div>
|
||||
@@ -1356,8 +1356,110 @@
|
||||
});
|
||||
|
||||
|
||||
// document.addEventListener('DOMContentLoaded', () => {
|
||||
// // 1. 获取元素(匹配你的结构)
|
||||
// const carouselImgs = document.querySelector('.carousel-imgs');
|
||||
// const imgItems = document.querySelectorAll('.carousel-img');
|
||||
// const leftArrow = document.querySelector('.arrow-left');
|
||||
// const rightArrow = document.querySelector('.arrow-right');
|
||||
// const textItems = document.querySelectorAll('.carousel-text');
|
||||
// const carouselContainer = document.querySelector('.carousel-container');
|
||||
|
||||
// // 容错处理
|
||||
// if (!carouselImgs || imgItems.length === 0) {
|
||||
// console.warn('轮播图片为空,初始化终止');
|
||||
// return;
|
||||
// }
|
||||
|
||||
// // 2. 核心变量(仅索引,无尺寸计算)
|
||||
// const imgCount = imgItems.length;
|
||||
// let currentIndex = 0;
|
||||
// let autoPlayTimer = null;
|
||||
// let isResizing = false; // 缩放锁,避免重复触发
|
||||
|
||||
// // 3. 切换到指定索引(核心:百分比偏移,无尺寸计算)
|
||||
// const goToIndex = (index) => {
|
||||
// // 边界处理
|
||||
// if (index < 0) index = imgCount - 1;
|
||||
// if (index >= imgCount) index = 0;
|
||||
|
||||
// // 关键:用百分比偏移,彻底避开rem/px计算误差
|
||||
// carouselImgs.style.transform = `translateX(-${index * 100}%)`;
|
||||
// currentIndex = index;
|
||||
|
||||
// // 更新文字激活态
|
||||
// textItems.forEach((item, idx) => {
|
||||
// item.classList.toggle('active', idx === currentIndex);
|
||||
// });
|
||||
// };
|
||||
|
||||
// // 4. 左右切换逻辑
|
||||
// const slideNext = () => goToIndex(currentIndex + 1);
|
||||
// const slidePrev = () => goToIndex(currentIndex - 1);
|
||||
|
||||
// // 5. 自动播放逻辑
|
||||
// const autoPlay = () => {
|
||||
// clearInterval(autoPlayTimer);
|
||||
// autoPlayTimer = setInterval(slideNext, 3000); // 3秒切换,可改
|
||||
// };
|
||||
|
||||
// // 6. 绑定事件
|
||||
// // 箭头点击
|
||||
// leftArrow?.addEventListener('click', () => {
|
||||
// slidePrev();
|
||||
// autoPlay(); // 点击后重启自动播放
|
||||
// });
|
||||
// rightArrow?.addEventListener('click', () => {
|
||||
// slideNext();
|
||||
// autoPlay();
|
||||
// });
|
||||
|
||||
// // 文字指示器点击
|
||||
// textItems.forEach((item, idx) => {
|
||||
// item.addEventListener('click', () => {
|
||||
// goToIndex(idx);
|
||||
// autoPlay();
|
||||
// });
|
||||
// });
|
||||
|
||||
// // 鼠标悬停暂停
|
||||
// carouselContainer?.addEventListener('mouseenter', () => {
|
||||
// clearInterval(autoPlayTimer);
|
||||
// });
|
||||
// carouselContainer?.addEventListener('mouseleave', autoPlay);
|
||||
|
||||
// // 7. 窗口缩放响应(核心:仅重新定位,无计算)
|
||||
// const handleResize = () => {
|
||||
// if (isResizing) return;
|
||||
// isResizing = true;
|
||||
|
||||
// // 缩放时直接重新定位当前索引(百分比偏移无需计算)
|
||||
// goToIndex(currentIndex);
|
||||
|
||||
// // 解锁
|
||||
// setTimeout(() => {
|
||||
// isResizing = false;
|
||||
// }, 100);
|
||||
// };
|
||||
|
||||
// // 防抖监听窗口缩放
|
||||
// let resizeTimer;
|
||||
// window.addEventListener('resize', () => {
|
||||
// clearTimeout(resizeTimer);
|
||||
// resizeTimer = setTimeout(handleResize, 150);
|
||||
// });
|
||||
|
||||
// // 8. 初始化
|
||||
// goToIndex(0); // 初始定位到第一张
|
||||
// autoPlay(); // 启动自动播放
|
||||
|
||||
// // 9. 页面卸载清理定时器
|
||||
// window.addEventListener('beforeunload', () => {
|
||||
// clearInterval(autoPlayTimer);
|
||||
// });
|
||||
// });
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
// 1. 获取元素(匹配你的结构)
|
||||
// 1. 获取元素
|
||||
const carouselImgs = document.querySelector('.carousel-imgs');
|
||||
const imgItems = document.querySelectorAll('.carousel-img');
|
||||
const leftArrow = document.querySelector('.arrow-left');
|
||||
@@ -1371,87 +1473,142 @@ document.addEventListener('DOMContentLoaded', () => {
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 核心变量(仅索引,无尺寸计算)
|
||||
const imgCount = imgItems.length;
|
||||
let currentIndex = 0;
|
||||
// 2. 核心配置
|
||||
const imgCount = imgItems.length; // 真实图片数量(如3张:1/2/3)
|
||||
let currentRealIndex = 0; // 真实图片索引(0=1, 1=2, 2=3)
|
||||
let isTransitioning = false; // 过渡锁,防止动画冲突
|
||||
const transitionDuration = 500; // 过渡时长(ms),需与CSS一致
|
||||
let autoPlayTimer = null;
|
||||
let isResizing = false; // 缩放锁,避免重复触发
|
||||
|
||||
// 3. 切换到指定索引(核心:百分比偏移,无尺寸计算)
|
||||
const goToIndex = (index) => {
|
||||
// 边界处理
|
||||
if (index < 0) index = imgCount - 1;
|
||||
if (index >= imgCount) index = 0;
|
||||
// 3. 初始化无缝DOM:仅复制第一张到末尾(适配3→1右侧滑入)
|
||||
const initSeamless = () => {
|
||||
// 复制第一张图片(1)到轮播容器末尾
|
||||
const firstImgCopy = imgItems[0].cloneNode(true);
|
||||
carouselImgs.appendChild(firstImgCopy);
|
||||
// 初始定位:无过渡,显示真实第一张
|
||||
carouselImgs.style.transition = 'none';
|
||||
carouselImgs.style.transform = `translateX(0%)`;
|
||||
void carouselImgs.offsetWidth; // 强制重绘
|
||||
// 开启过渡
|
||||
carouselImgs.style.transition = `transform ${transitionDuration}ms ease`;
|
||||
};
|
||||
initSeamless();
|
||||
|
||||
// 关键:用百分比偏移,彻底避开rem/px计算误差
|
||||
carouselImgs.style.transform = `translateX(-${index * 100}%)`;
|
||||
currentIndex = index;
|
||||
// 4. 核心切换函数(保证3→1时1从右侧滑入)
|
||||
const slideToNext = () => {
|
||||
if (isTransitioning) return;
|
||||
isTransitioning = true;
|
||||
|
||||
// 更新文字激活态
|
||||
textItems.forEach((item, idx) => {
|
||||
item.classList.toggle('active', idx === currentIndex);
|
||||
});
|
||||
// 步骤1:计算目标偏移,执行滑动动画
|
||||
const targetTranslateX = -(currentRealIndex + 1) * 100;
|
||||
carouselImgs.style.transform = `translateX(${targetTranslateX}%)`;
|
||||
|
||||
// 步骤2:监听过渡结束,处理无缝逻辑
|
||||
const handleEnd = () => {
|
||||
carouselImgs.removeEventListener('transitionend', handleEnd);
|
||||
isTransitioning = false;
|
||||
|
||||
// 如果滑到了复制的第一张(3→1的视觉终点)
|
||||
if (currentRealIndex === imgCount - 1) {
|
||||
// 瞬间切回真实第一张(无过渡,用户无感知)
|
||||
carouselImgs.style.transition = 'none';
|
||||
carouselImgs.style.transform = `translateX(0%)`;
|
||||
void carouselImgs.offsetWidth;
|
||||
carouselImgs.style.transition = `transform ${transitionDuration}ms ease`;
|
||||
currentRealIndex = 0; // 重置为真实第一张
|
||||
} else {
|
||||
currentRealIndex += 1; // 正常切换,索引+1
|
||||
}
|
||||
|
||||
// 更新文字指示器激活态
|
||||
textItems.forEach((item, idx) => {
|
||||
item.classList.toggle('active', idx === currentRealIndex);
|
||||
});
|
||||
};
|
||||
carouselImgs.addEventListener('transitionend', handleEnd);
|
||||
};
|
||||
|
||||
// 4. 左右切换逻辑
|
||||
const slideNext = () => goToIndex(currentIndex + 1);
|
||||
const slidePrev = () => goToIndex(currentIndex - 1);
|
||||
// 5. 反向切换(1→3,可选保留)
|
||||
const slideToPrev = () => {
|
||||
if (isTransitioning) return;
|
||||
isTransitioning = true;
|
||||
|
||||
// 5. 自动播放逻辑
|
||||
// 1→3时,先瞬间切到复制的3位置,再滑入
|
||||
if (currentRealIndex === 0) {
|
||||
carouselImgs.style.transition = 'none';
|
||||
carouselImgs.style.transform = `translateX(-${imgCount * 100}%)`;
|
||||
void carouselImgs.offsetWidth;
|
||||
carouselImgs.style.transition = `transform ${transitionDuration}ms ease`;
|
||||
currentRealIndex = imgCount - 1;
|
||||
}
|
||||
|
||||
const targetTranslateX = -currentRealIndex * 100;
|
||||
carouselImgs.style.transform = `translateX(${targetTranslateX}%)`;
|
||||
|
||||
const handleEnd = () => {
|
||||
carouselImgs.removeEventListener('transitionend', handleEnd);
|
||||
isTransitioning = false;
|
||||
// 更新文字指示器
|
||||
textItems.forEach((item, idx) => {
|
||||
item.classList.toggle('active', idx === currentRealIndex);
|
||||
});
|
||||
};
|
||||
carouselImgs.addEventListener('transitionend', handleEnd);
|
||||
};
|
||||
|
||||
// 6. 自动播放:严格1→2→3→1循环
|
||||
const autoPlay = () => {
|
||||
clearInterval(autoPlayTimer);
|
||||
autoPlayTimer = setInterval(slideNext, 3000); // 3秒切换,可改
|
||||
autoPlayTimer = setInterval(() => {
|
||||
if (!isTransitioning) slideToNext();
|
||||
}, 3000); // 3秒切换一次,可调整
|
||||
};
|
||||
|
||||
// 6. 绑定事件
|
||||
// 箭头点击
|
||||
leftArrow?.addEventListener('click', () => {
|
||||
slidePrev();
|
||||
// 7. 事件绑定
|
||||
// 右箭头:下一张(核心,保证3→1右侧滑入)
|
||||
rightArrow?.addEventListener('click', () => {
|
||||
slideToNext();
|
||||
autoPlay(); // 点击后重启自动播放
|
||||
});
|
||||
rightArrow?.addEventListener('click', () => {
|
||||
slideNext();
|
||||
// 左箭头:上一张(可选,如需取消可注释)
|
||||
leftArrow?.addEventListener('click', () => {
|
||||
slideToPrev();
|
||||
autoPlay();
|
||||
});
|
||||
|
||||
// 文字指示器点击
|
||||
textItems.forEach((item, idx) => {
|
||||
item.addEventListener('click', () => {
|
||||
goToIndex(idx);
|
||||
if (isTransitioning || currentRealIndex === idx) return;
|
||||
isTransitioning = true;
|
||||
|
||||
// 直接滑到目标图片
|
||||
carouselImgs.style.transform = `translateX(-${idx * 100}%)`;
|
||||
currentRealIndex = idx;
|
||||
|
||||
// 过渡结束解锁
|
||||
const handleEnd = () => {
|
||||
carouselImgs.removeEventListener('transitionend', handleEnd);
|
||||
isTransitioning = false;
|
||||
};
|
||||
carouselImgs.addEventListener('transitionend', handleEnd);
|
||||
|
||||
autoPlay();
|
||||
});
|
||||
});
|
||||
|
||||
// 鼠标悬停暂停
|
||||
// 鼠标悬停暂停/恢复
|
||||
carouselContainer?.addEventListener('mouseenter', () => {
|
||||
clearInterval(autoPlayTimer);
|
||||
});
|
||||
carouselContainer?.addEventListener('mouseleave', autoPlay);
|
||||
|
||||
// 7. 窗口缩放响应(核心:仅重新定位,无计算)
|
||||
const handleResize = () => {
|
||||
if (isResizing) return;
|
||||
isResizing = true;
|
||||
|
||||
// 缩放时直接重新定位当前索引(百分比偏移无需计算)
|
||||
goToIndex(currentIndex);
|
||||
|
||||
// 解锁
|
||||
setTimeout(() => {
|
||||
isResizing = false;
|
||||
}, 100);
|
||||
};
|
||||
|
||||
// 防抖监听窗口缩放
|
||||
let resizeTimer;
|
||||
window.addEventListener('resize', () => {
|
||||
clearTimeout(resizeTimer);
|
||||
resizeTimer = setTimeout(handleResize, 150);
|
||||
});
|
||||
|
||||
// 8. 初始化
|
||||
goToIndex(0); // 初始定位到第一张
|
||||
autoPlay(); // 启动自动播放
|
||||
// 激活第一个文字指示器
|
||||
textItems.forEach((item, idx) => {
|
||||
item.classList.toggle('active', idx === 0);
|
||||
});
|
||||
autoPlay(); // 启动自动播放
|
||||
|
||||
// 9. 页面卸载清理定时器
|
||||
window.addEventListener('beforeunload', () => {
|
||||
|
||||
Reference in New Issue
Block a user