本文通过一个完整的全景轮播示例,解析如何利用HTML结构、CSS定位与过渡动画、JavaScript DOM操作和节流控制,实现类似画廊的横向滚动轮播效果。适用于需要展示多张图片并支持手动切换的场景。
- <div class="container">
- <div id="slide">
- <div class="item" style="background-image:url('./img/photo01.jpg')"></div>
- <div class="item" style="background-image:url('./img/photo02.jpg')"></div>
- <div class="item" style="background-image:url('./img/photo03.jpg')"></div>
- <div class="item" style="background-image:url('./img/photo04.jpg')"></div>
- <div class="item" style="background-image:url('./img/photo05.jpg')"></div>
- <div class="item" style="background-image:url('./img/photo06.jpg')"></div>
- </div>
- <div class="buttons">
- <div class="left">< Prev</div>
- <div class="center">下载壁纸</div>
- <div class="right">Next ></div>
- </div>
- </div>
复制代码
首先,全局样式重置,所有元素使用border-box盒模型,避免宽高计算偏差。
- * {
- margin: 0;
- padding: 0;
- box-sizing: border-box;
- }
复制代码
容器.container设置为全屏宽高(100vw/100vh),相对定位,溢出隐藏,确保超出部分不显示。
- .container {
- width: 100vw;
- height: 100vh;
- position: relative;
- overflow: hidden;
- }
复制代码
每个.item初始为宽240px、高160px的绝对定位元素,垂直居中(top:50%, transform:translateY(-50%)),圆角10px,带阴影,背景图cover铺满并居中,并设置1秒过渡动画。
- .item {
- width: 240px;
- height: 160px;
- position: absolute;
- top: 50%;
- left: 0;
- transform: translateY(-50%);
- border-radius: 10px;
- box-shadow: 0 30px 50px #505050;
- background-size: cover;
- background-position: center;
- transition: 1s;
- }
复制代码
关键在于利用nth-child选择器定义不同位置的item,实现“全景”效果:第1、2个.item覆盖全屏(宽高100%、无阴影、无圆角),作为当前展示的大图;第3个.item位于left:70%(即右侧缩略图起始位置);第4个.item左偏移calc(70% + 250px);第5个.item左偏移calc(70% + 500px);第6个及之后的item继续偏移750px且opacity:0,实现隐藏。
- .item:nth-child(1),
- .item:nth-child(2) {
- left: 0;
- top: 0;
- width: 100%;
- height: 100%;
- transform: translateY(0);
- box-shadow: none;
- border-radius: 0;
- }
- .item:nth-child(3) {
- left: 70%;
- }
- .item:nth-child(4) {
- left: calc(70% + 250px);
- }
- .item:nth-child(5) {
- left: calc(70% + 500px);
- }
- .item:nth-child(n+6) {
- left: calc(70% + 750px);
- opacity: 0;
- }
复制代码
按钮容器.buttons固定在底部,使用flex居中对齐。子按钮宽120px、高50px,半透明背景,白色文字,圆角5px,并设置cursor:pointer和user-select:none防止文本选中。
- .buttons {
- width: 100%;
- position: absolute;
- bottom: 50px;
- margin-left: -50px;
- text-align: center;
- display: flex;
- justify-content: center;
- }
- .buttons div {
- width: 120px;
- height: 50px;
- line-height: 50px;
- text-align: center;
- border-radius: 5px;
- margin: 0 25px;
- transition: .5s;
- cursor: pointer;
- user-select: none;
- font-size: 20px;
- color: #fff;
- background-color: rgba(0, 0, 0, 0.4);
- box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.2);
- }
复制代码
关键逻辑在JavaScript中实现循环轮播。通过“上一张”按钮点击时,将最后一个item移动到slide最前面(prepend);“下一张”按钮则将第一个item追加到最后(appendChild)。配合CSS的transition动画,会产生流畅的位移效果。为防止动画期间重复点击导致错乱,引入节流变量openClick,点击后立即设为false,1秒后(与transition时长一致)再恢复为true。
- const leftBtn = document.querySelector(".buttons .left")
- const rightBtn = document.querySelector(".buttons .right")
- const slide = document.querySelector("#slide")
- let openClick = true
- leftBtn.addEventListener("click", () => {
- if (openClick) {
- openClick = false
- const items = document.querySelectorAll(".item")
- slide.prepend(items[items.length - 1])
- setTimeout(() => openClick = true, 1000)
- }
- })
- rightBtn.addEventListener("click", () => {
- if (openClick) {
- openClick = false
- const items = document.querySelectorAll(".item")
- slide.appendChild(items[0])
- setTimeout(() => openClick = true, 1000)
- }
- })
复制代码
此实现无需复杂计算偏移量,仅依靠DOM元素顺序变化和CSS预定义定位,即可实现全景轮播效果。节流处理避免了快速点击导致的动画冲突,是常见轮播组件的精简方案。注意图片路径需替换为实际资源,且每个.item的background-image通过inline style指定。 |