本文使用了纯JS创建轮播图,通过封装的函数来创建元素并添加到父元素中来实现样式。
思路是:页面始终显示一张图片,当滚动时 在前面或后面添加下一张图片 然后达到指定位置时 把之前的图片删除
在使用时只需要把 imgSrcList(图片地址数组)、aHrefList(图片对应超链接数组)、 btnSrcList(左右按钮图片地址)、WIDTH(定义的每张图片的宽度)、HEIGHT(定义的每张图片的高度) 进行相应的修改即可。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// carousel 是整个包含轮播图的大容器
// imgCon 是用来显示需要轮播的图片的容器
// dots 是包含所有小圆点的容器(ul)
let carousel,imgCon,dots;
// imgSrcList 是用来存放图片地址的 后期可以只修改这个地址即可
// aHrefList 是每一张图片对应的链接 也是后期直接修改即可使用
// btnSrcList 是用来存放左右按钮图片地址的 后期可以只修改这个地址即可
// dotList 是用来存放小圆点的数组 方便遍历查找
// aList 是用来存放创建的每一个超链接标签 每一个超链接标签内包含对应图片
// bnList 是点击的向左向右按钮的数组
let imgSrcList = ["./img/a.png","./img/b.png","./img/c.png","./img/d.png","./img/e.png"],
aHrefList = ["http://qq.com","http://163.com","http://jd.com","http://taobao.com","http://baidu.com"],
btnSrcList = ["./img/left.png","./img/right.png"],
dotList = [],
aList = [],
bnList = [];
// pos 是应该显示的图片的索引
// x 是imgCon(显示需要轮播的图片的容器)的偏移left值
// direction 是imgCon应该移动的方向 如果点击向左 imgCon就向右移动 反之向左移动
// prevDot 是显示红色的小圆点 其余为白色
// bool 是控制不能连续点击的开关
// autoBool 是控制自动播放的开关 当为true的时候 执行自动轮播 false的时候 自动轮播事件会跳出 执行不了
// time 是自动轮播时 移动完需要等待一段的时间
let pos = 0,
x = 0,
direction="",
prevDot,
bool = false,
autoBool = true,
time = 200;
// WIDTH 是定义的每张图片的宽度
// HEIGHT 是定义的每张图片的高度
// SPEED 是步长
// LEFT RIGHT 是定义的方向 防止别人修改重定义,所以使用Symbol()
const WIDTH = 1500;
const HEIGHT = 500;
const SPEED = 20;
const LEFT = Symbol();
const RIGHT = Symbol();
// 封装的创建元素的函数 参数为创建元素的标签和样式
function ce(type,style){
// 创建一个标签 类型是传入的type参数
let elem = document.createElement(type);
// 将写入的样式赋值给创建元素的样式
Object.assign(elem.style,style);
// 将这个创建好的元素返回出去
return elem;
}
// 初始化函数
init();
// 在初始化函数中 创建整个包含轮播图的大容器 添加样式 并通过appendChild添加到body中
// 在这里执行创建ImgCon、Dots、Btn的函数 并把carousel作为参数传入
// 初始化时执行改变小圆点的函数 让一开始第一个小圆点为红色
// 给carousel 添加移入移出事件 来阻止自动轮播
function init(){
var carousel = ce("div",{
width:WIDTH+'px',
height:HEIGHT+'px',
position:"relative",
left:0,
right:0,
top:0,
bottom:0,
margin:"auto",
overflow:"hidden"
})
createImgCon(carousel);
createDot(carousel);
createBtn(carousel);
changeDot();
setInterval(animation,16)
document.body.appendChild(carousel);
carousel.addEventListener("mouseenter",mouseHandler);
carousel.addEventListener("mouseleave",mouseHandler);
}
// 创建imgCon的函数 参数为imgCon应该放入的父元素(carousel)
// 遍历图片地址数组 创建对应的a标签 再创建img标签
// 将图片地址数组中的每一项赋给创建的图片 再把img放入a标签内
// 将链接地址数组中的每一项赋给a标签的href属性 把a添加到aList数组中,并添加到父元素中
function createImgCon(parent){
imgCon = ce("div",{
width:WIDTH*2 + 'px',
height:HEIGHT +'px',
position:"absolute",
left:0,
backgroundColor:"pink",
})
imgSrcList.forEach((item,index)=>{
aCon = ce("a",{
display:"block",
width:WIDTH +'px',
height:HEIGHT+'px',
float:"left"
})
img = ce("img",{
width:WIDTH+'px',
height:HEIGHT+'px',
})
img.src = item;
aCon.appendChild(img);
aCon.href = aHrefList[index];
aCon.target = "_blank"
aList.push(aCon);
})
// console.log(aList);
imgCon.appendChild(aList[0]);
parent.appendChild(imgCon)
}
// 创建小圆点的函数 参数为dots(ul标签)应该放入的父元素(carousel)
// 遍历图片地址数组 根据数组中的数量来创建对应数量的小圆点
// 把所有小圆点放到dotList数组中 并添加到dots(ul)元素中
// 给dots(ul)添加清楚浮动的属性 再把ul添加到父元素中
// 创建完天津爱点击事件
function createDot(parent){
dots = ce("ul",{
listStyle:"none",
position:"absolute",
left:"50%",
bottom:"30px",
transform:"translateX(-50%)",
})
imgSrcList.forEach((item,index)=>{
var li = ce("li",{
width:"24px",
height:"24px",
borderRadius:"50%",
marginRight:index===imgSrcList.length-1 ? '0px' : '20px',
float:"left",
backgroundColor:"rgba(255,255,255,0.8)"
})
dotList.push(li);
dots.appendChild(li)
})
var clear_fix = {
clear:"both",
display:"block",
content:""
}
dots.setAttribute("class",clear_fix);
// console.log(dotList);
parent.appendChild(dots)
dots.addEventListener("click",dotClickHandler);
}
// 创建左右按钮的函数 与上面创建图片类似
// 创建完绑定点击事件
function createBtn(parent){
btnSrcList.forEach((item,index)=>{
var img = ce('img',{
width:"30px",
height:"60px",
position:"absolute",
top:"50%",
transform:"translateY(-50%)",
left: index===0 ? '50px' : "",
right: index === 1 ? '50px' : ''
})
img.src = item;
bnList.push(img);
parent.appendChild(img);
img.addEventListener("click",btnClickHandler);
})
}
// 左右按钮点击事件
// 如果点击的是左边的按钮 图片对应的索引应该自减1
// 如果小于0 了 就让他等于图片地址数组的长度-1
// 并规定方向为右
// 点击右按钮与之相反
// 点击的时候执行创建下一张图片的函数
function btnClickHandler(e){
if(bool) return;
e = e || window.event;
if(this.src.includes("left.png")){
pos--;
if(pos<0) pos = imgSrcList.length-1;
direction = RIGHT;
}else if(this.src.includes("right.png")){
pos++;
if(pos>imgSrcList.length-1) pos = 0;
direction = LEFT;
}
createNextImg();
}
// 小圆点的点击按钮函数
// 因为这个事件是委托给ul的 所以当点击的不是Li时就跳出 不继续执行
// 获取我点击的是小圆点数组中的第几个 获取对应下标
// 如果我点击的小圆点的下标与现在的pos相同 就跳出 不执行
// 如果点击的小圆点的下标大于现在的pos 就是向左运动 反之向右运动
// 然后把获取的下标再赋给pos
// 完成上述内容 执行创建下一张图片的函数
function dotClickHandler(e){
if(bool) return;
e = e || window.event;
if(e.target.nodeName !== "LI") return;
let index = dotList.indexOf(e.target);
if(index === pos) return;
direction = index>pos ? LEFT : RIGHT;
pos = index;
createNextImg();
}
// 创建下一张图片的函数
// 如果是向左走 那说明是在imgCon后面添加一张图片
// 如果是向右走 那说明是在imgCon前面添加一张图片 然后再定位到-WIDTH的位置
// 创建图片的同时 执行改变小圆点的函数
function createNextImg(){
if(direction === LEFT){
imgCon.appendChild(aList[pos]);
x=0;
}else if(direction === RIGHT){
imgCon.insertBefore(aList[pos],imgCon.firstElementChild);
imgCon.style.left = -WIDTH +"px";
x= -WIDTH;
}
bool = true;
changeDot();
}
// 改变小圆点的函数
// 如果之前有小圆点 就让之前的小圆点的背景变为白色
// 然后把当前的点击的小圆点赋值给prevDot 再改变这个的样式
function changeDot(){
if(prevDot){
prevDot.style.backgroundColor = "rgba(255,255,255,0.8)";
}
prevDot = dotList[pos];
prevDot.style.backgroundColor = "rgba(255,0,0,0.8)"
}
// 定时器添加动画 和自动播放
function animation(){
imgConMove();
autoPlay();
}
// 如果是向左走
// 让x一点点减 如果减到小于-WIDTH的位置 说明后面的图片已经移动到目标位置 这时把第一张图片删除 并让x=0
// 如果是向右走
// 让x一点点加 如果加到0的位置 说明前面的图片已经移动到目标位置 这时把后面的那张图片删除 并让x=0
function imgConMove(){
if(!bool) return;
if(direction === LEFT){
x -= SPEED;
if(x <= -WIDTH){
imgCon.firstElementChild.remove();
x = 0;
bool = false;
}
imgCon.style.left = x +'px';
}else if(direction === RIGHT){
x += SPEED;
if(x >= 0){
imgCon.lastElementChild.remove();
x = 0;
bool = false;
}
imgCon.style.left = x +'px';
}
}
// 添加自动轮播事件
// 先让time-- 当time减到小于0的时候 执行下面的代码 让time重新变成200
// 并创建一个鼠标点击事件 抛发给右边的按钮 这样就相当于点击右边的按钮 从而实现自动轮播
function autoPlay(){
if(!autoBool) return;
time--;
if(time>0) return;
time=200;
let evt = new MouseEvent("click");
bnList[1].dispatchEvent(evt);
}
//给整个轮播图添加移入移出事件
// 当是移入事件的时候 让autoBool改为false 并将time重新设为200
// 当是移除事件的时候 将autoBool设为true 就可以继续自动播放
function mouseHandler(e){
e = e || window.event;
if(e.type === "mouseenter"){
autoBool = false;
time = 200;
}else if(e.type === "mouseleave"){
autoBool = true;
}
}
</script>
</body>
</html>