撸一波,节点增删实现无缝轮播。
同步 github 地址 无缝轮播
代码说话吧?
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Document</title>
<style>
* {
padding: 0;
margin: 0;
}
.box,
.run {
width: 300px;
}
.box {
height: 187px;
border: chocolate 1px solid;
position: relative;
overflow: hidden;
margin: 10px auto;
}
.left,
.right {
font-size: 20px;
font-family: 'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif;
position: absolute;
width: 30px;
height: 30px;
text-align: center;
line-height: 30px;
top: 50%;
transform: translateY(-50%);
}
.left {
left: 0;
}
.right {
right: 0;
}
.motion {
height: 100%;
font-size: 50px;
position: absolute;
left: 0;
}
.run {
display: inline-block;
float: left;
height: 100%;
line-height: 187px;
text-align: center;
position: relative;
top: 0;
}
.run img {
width: 100%;
position: absolute;
top: 0;
left: 0;
}
.run1 {
background: brown;
}
.run2 {
background: burlywood;
}
.run3 {
background: chartreuse;
}
.run4 {
background: chocolate;
}
.run5 {
background: cyan;
}
</style>
</head>
<body>
<div class="box">
<div class="motion" style="transition: all 0.3s linear;"></div>
<div class="left">L</div>
<div class="right">R</div>
</div>
</body>
</html>
<script src="index.js"></script>
<script>
let arr = ["<img src='./1.jpeg'>", 2, "<img src='./2.jpeg'>", 4, "<img src='./3.jpeg'>"];
let width = 300;
// 轮播数组,轮播图宽度,自动轮播延迟时间。
new runload(arr, width, 2000);
</script>
javascript
/**
* 轮播
* @param { Array } arr 传入需要轮播的数组,的可以是文本也可以是节点
* @param { Number } width 轮播图的宽度
* @param { Number } delay 轮播延迟时间
*/
function runload(arr, width, delay) {
let i = 0;
let len = arr.length;
let clickable = true; // 轮播的情况下设置不可点击
let motion = document.querySelector('.motion'); // 父节点
let transition = 'transition:' + motion.style.transition + ';'; // 过度属性,获取style设置的transition属性值。
let time = motion.style.transition.split(' ')[1].split('s')[0] * 1000; // 根据过度时间,设置轮播图定时器时间
/**
* 创建节点
* @param {*} element 传入arr数组内容
* @param {*} index 传入arr数组下标
*/
let createNode = function(element, index) {
motion.setAttribute('style', 'width:' + width * element + 'px;');
let node = document.createElement('div');
node.setAttribute('class', 'run run' + (index + 1));
node.innerHTML = element;
motion.appendChild(node);
};
arr.forEach((element, index) => {
createNode(element, index);
});
/**
* 克隆节点
* @param {*} type 克隆第一个还是最后一个
* @description 这里只克隆头尾
* @returns 克隆的节点
*/
function clone(type) {
if (type === 'first') {
let node = motion.firstChild.cloneNode();
node.innerHTML = motion.firstChild.innerHTML;
return node;
} else {
let node = motion.lastChild.cloneNode();
node.innerHTML = motion.lastChild.innerHTML;
return node;
}
}
// ?向左
let left = () => {
clearInterval(this.timer); // 停止轮播
if (clickable === false) return false;
clickable = false;
i <= 0 ? (i = len - 1) : i--;
// 向左运行的时候先克隆最后一个节点,插入到第一个。
motion.insertBefore(clone('last'), motion.childNodes[0]);
run();
let runleft = Number(motion.style.left.split('px')[0]) + 0;
motion.setAttribute('style', 'transition: all 0s;width:' + width * len + 'px;' + 'left:' + -width + 'px;');
setTimeout(() => {
motion.setAttribute('style', transition + 'width:' + width * len + 'px;' + 'left:' + runleft + 'px');
}, 1);
// 删除最后一个节点,还原轮播长度。
setTimeout(() => {
motion.removeChild(motion.lastChild);
motion.setAttribute('style', 'transition: all 0s;width:' + width * len + 'px;' + 'left:' + 0 + 'px;');
clickable = true;
this.timer = setInterval(right, delay); // 开启
}, time);
};
// 向右?
let right = () => {
clearInterval(this.timer); // 停止轮播
if (clickable === false) return false;
clickable = false;
i >= len - 1 ? (i = 0) : i++;
let run_element = run();
let runright = Number(motion.style.left.split('px')[0]) - width;
motion.setAttribute('style', transition + 'width:' + width * len + 'px;' + 'left:' + runright + 'px');
// 向右运行的时候删除第一个节点,添加到末尾
setTimeout(() => {
motion.setAttribute('style', 'transition: all 0s;width:' + width * len + 'px;' + 'left:' + 0 + 'px;');
motion.removeChild(run_element);
motion.appendChild(run_element);
clickable = true;
this.timer = setInterval(right, delay); // 开启
}, time);
};
// 返回当前运行的节点
function run() {
let run_index = i === 0 ? len : i;
let run = {};
run[run_index] = document.querySelector('.run' + run_index);
return run[run_index];
}
this.timer = setInterval(right, delay); // 自动轮播
document.getElementsByClassName('right')[0].addEventListener('click', right);
document.getElementsByClassName('left')[0].addEventListener('click', left);
}