轮播图是网页设计中常见的元素之一,它能够以动画效果展示多张图片或内容,为用户提供更好的视觉体验。通过轮播图,我们可以在有限的空间内展示多个信息,如产品特点、广告宣传、新闻资讯等。在移动端适配方面,轮播图的设计需要考虑屏幕尺寸、触摸交互等因素,以确保在不同设备上都能良好展示,并提供流畅的触摸滑动体验。本文将介绍一些常用的移动端轮播图实现方法和技巧,帮助开发者在移动端设计中有效应用轮播图组件。
首先准备基本骨架和五张图片数据,找到banner容器,通过for of循环,创建img标签并设置img的src属性,追加到banner容器中,初始化完成。
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>bannertitle>
<style>
.container {
height: 300px;
width: 300px;
}
.banner {
height: 300px;
display: flex;
}
img {
width: 300px;
height: 300px;
}
style>
head>
<body>
<div class="container">
<div class="banner">div>
div>
<button class="pre">上一张button>
<button class="next">下一张button>
<script>
const state = {
imgList:[
'./image/head.jpg',
'./image/js.jpg',
'./image/mobile.png',
'./image/qrcode.jpg',
'./image/Vue.jpg',
],
}
let bannerEl = document.querySelector('.banner')
const init = () => {
for(let img of state.imgList){
const imgEl = document.createElement('img')
imgEl.src = img
bannerEl.append(imgEl)
}
}
init()
script>
body>
html>
我们需要在全局state里定义一个定时器变量(用户存储和销毁定时器)和一个当前图片下标变量。
const state = {
imgList: [
'./image/head.jpg',
'./image/js.jpg',
'./image/mobile.png',
'./image/qrcode.jpg',
'./image/Vue.jpg',
],
timer: null,
curIndex: 0
}
封装一个开启滚动的方法startRoll,启动滚动时就获取banner下的图片元素集合,并开启定时器,执行滚动事件。
/**
* 启动滚动
*/
const startRoll = () => {
imgListEl = bannerEl.children
state.timer = setInterval(handleRoll, 1000)
}
这里handleRoll方法需要进行封装一下,当每次滚动时,将state.curIndex进行自增,同时将banner向左移动-state.curIndex * 100%的距离,然后再加上动画。
/**
* 滚动
*/
const handleRoll = () => {
state.curIndex++
bannerEl.style.transform = `translateX(-${state.curIndex * 100}%)`
bannerEl.style.transition = `all .5s ease`
}
最后再封装一个关闭定时器的方法,使用clearInterval清除定时器,并且将state.timer置为空。
/**
* 关闭滚动
*/
const endRoll = () => {
clearInterval(state.timer)
state.timer = null;
}
最后,将startRoll方法放在init方法里,当所有图片挂载完成时,执行轮播。
完成上述操作后,会发现banner不断地向左滚动,所以,这里我们需要进行边界处理。改动我们的handleRoll滚动方法,判断state.curIndex,如果它大于等于我们图片列表的长度,将它置为0。
/**
* 滚动
*/
const handleRoll = () => {
state.curIndex++
if(state.curIndex >= imgListEl.length){
state.curIndex = 0
}
bannerEl.style.transform = `translateX(-${state.curIndex * 100}%)`
bannerEl.style.transition = `all .5s ease`
}
改动完,我们可以看到当最后一张图片滚动到下一张时,会滚回第一张图片。所以我们需要实现无限轮播的效果。
这里介绍一种实现无缝轮播效果的思路,就是将初始图片数据的收尾图片相互增加前后,效果如下图所示:
需要修改初始状态,将state.curIndex进行自增,同时将banner向左移动100%。
/**
* 初始化
*/
const init = () => {
const firstImg = state.imgList[0]
const lastImg = state.imgList[state.imgList.length - 1]
state.imgList.unshift(lastImg)
state.imgList.push(firstImg)
state.curIndex++
bannerEl.style.transform = `translateX(-${state.curIndex * 100}%)`
for (let img of state.imgList) {
const imgEl = document.createElement('img')
imgEl.src = img
bannerEl.append(imgEl)
}
startRoll()
}
关键点:当图片移动到倒数第二张时,我们需要改变banner移动的位置,将其移动到第一张图片的位置,同时去除动画,我们封装两个方法,一个是触发上一张的方法,一个是触发下一张的方法。当我们点击下一张时,判断是否为最后一张,是的话将state.curIndex置为1,并且重置到下标为1的位置。当我们点击上一张时,判断是否为-1,是的话将其滚动到最后一张的位置,再将state.curIndex置为倒数第二张的位置,立刻再向前滚动一张图片的距离。完整代码如下:
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>bannertitle>
<style>
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
.container {
height: 300px;
width: 300px;
overflow: hidden;
}
.banner {
height: 300px;
display: flex;
}
img {
width: 300px;
height: 300px;
}
style>
head>
<body>
<div class="container">
<div class="banner">div>
div>
<button class="pre">上一张button>
<button class="next">下一张button>
<script>
const state = {
imgList: [
'./image/head.jpg',
'./image/js.jpg',
'./image/mobile.png',
'./image/qrcode.jpg',
'./image/Vue.jpg',
],
timer: null,
curIndex: 0
}
/**获取banner容器*/
let bannerEl = document.querySelector('.banner')
/**获取图片标签*/
let imgListEl = null
const preBtnEl = document.querySelector('.pre')
const nextBtnEl = document.querySelector('.next')
/**
* 上一张
*/
const handlePreRoll = (e) => {
state.curIndex--
if (state.curIndex === -1) {
bannerEl.style.transform = `translateX(${-1 * (imgListEl.length) * 100}%)`
bannerEl.style.transition = `none`
state.curIndex = imgListEl.length - 2
setTimeout(() => {
bannerEl.style.transform = `translateX(${-1 * state.curIndex * 100}%)`
bannerEl.style.transition = `'all .5s ease`
}, 0);
console.log(state.curIndex)
} else {
bannerEl.style.transform = `translateX(${-state.curIndex * 100}%)`
bannerEl.style.transition = 'all .5s ease'
}
}
/**
* 下一张
*/
const handleNextRoll = (e) => {
state.curIndex++
bannerEl.style.transform = `translateX(-${state.curIndex * 100}%)`
bannerEl.style.transition = `all .5s ease`
if (state.curIndex === imgListEl.length - 1) {
state.curIndex = 1
setTimeout(() => {
bannerEl.style.transform = `translateX(-100%)`
bannerEl.style.transition = 'none'
}, 500);
}
}
preBtnEl.addEventListener('click', handlePreRoll)
nextBtnEl.addEventListener('click', handleNextRoll)
/**
* 初始化
*/
const init = () => {
const firstImg = state.imgList[0]
const lastImg = state.imgList[state.imgList.length - 1]
state.imgList.unshift(lastImg)
state.imgList.push(firstImg)
state.curIndex++
bannerEl.style.transform = `translateX(-${state.curIndex * 100}%)`
for (let img of state.imgList) {
const imgEl = document.createElement('img')
imgEl.src = img
bannerEl.append(imgEl)
}
startRoll()
}
/**
* 启动滚动
*/
const startRoll = () => {
imgListEl = bannerEl.children
state.timer = setInterval(handleNextRoll, 1000)
}
/**
* 关闭滚动
*/
const endRoll = () => {
clearInterval(state.timer)
state.timer = null;
}
init()
script>
body>
html>