一般而言轮播图都需要使用到动画效果,我这里是原生 js 手写一个动画,基于这个动画效果,在实现我们的轮播图。
封装了一个小插件,我把它命名为:slideshow .js
,源码如下:
function animate(elem, options, callback) {
if (elem == null){
//说明现在不是那个轮播图页面了
return;
}
let timer = null;
let attribute = options.attribute;
let startValue = parseFloat(window.getComputedStyle(elem)[attribute]);
let endValue = parseFloat(options.value);
let unit = options.value.substr(endValue.toString().length);
if (!options.fluency) {
options.fluency = 5;//流畅值,该值越小越流畅
}
if (startValue == endValue) {
if (callback != undefined) {
callback.call();
}
return;
}
function createTime() {
return (+new Date);
}
let startTime = createTime();
function logic() {
//开始时间 + 持续时间 - 当前时间,结果即为动画的剩余时间,当剩余时间小于0则置0,表示动画结束
let remaining = Math.max(0, startTime + options.duration - createTime());
//remaining/duration即为动画剩余的百分比,用1去减,得到已执行的百分比
let percent = 1 - (remaining / options.duration);
let nowValue = (endValue - startValue) * percent + startValue;
if (nowValue === 0){
elem.style[attribute] = nowValue;
} else {
elem.style[attribute] = nowValue + unit;
}
if (percent === 1) {
clearInterval(timer);
if (callback != undefined) {
callback.call();
}
return;
}
}
timer = setInterval(logic, options.fluency);
}
let slideshow = {
autoSlide:true,//是否自动轮播
animating:false,//当前对象是否正在执行动画
defaultWidth:1325,//对应于设计图1920px的宽度
width:1325,//根据当前屏幕宽度,适配的真正的宽度
unit:'px',
ulSelector:'.hot ul',
slideBoxSelector:'.slide-box',
intervals:[],//定时器的集合,当我们离开页面时,需要清除它们
next(){
if(slideshow.animating) return;
slideshow.animating = true;
let ul = document.querySelector(slideshow.ulSelector);
animate(ul, {attribute: 'left', value: -slideshow.width + slideshow.unit, duration:1500},function(){
ul.appendChild(ul.children[0]);
ul.style.left = 0;
slideshow.animating = false;
});
},
prevEvent:function(){
let prevButton = document.getElementsByClassName("prev")[0];
prevButton.onclick = function(){
if(slideshow.animating) return;
slideshow.animating = true;
let ul = document.querySelector(slideshow.ulSelector);
ul.style.left = -slideshow.width + slideshow.unit;
ul.insertBefore(ul.children[ul.children.length-1],ul.children[0]);
animate(ul,{ attribute: 'left', value: "0" + slideshow.unit, duration:1500},function(){
slideshow.animating = false;
});
}
},
nextEvent:function(){
let nextButton = document.getElementsByClassName("next")[0];
nextButton.onclick = function(){
slideshow.next();
}
},
init:function(){
function run(){
slideshow.autoSlide = true;
slideshow.animating = false;
slideshow.intervals = [];
let ul = document.querySelector(slideshow.ulSelector);
if (ul == undefined){
return;
}
let liArr = ul.getElementsByTagName("li");
if(liArr.length<=1) return;
let autoSlideInterval = setInterval(function(){
if(! slideshow.autoSlide) return;
slideshow.next();
},8000);
slideshow.intervals.push(autoSlideInterval);
let slideBox = document.querySelector(slideshow.slideBoxSelector);
slideBox.onmouseover = function(){
slideshow.autoSlide = false;
}
slideBox.onmouseout = function(){
slideshow.autoSlide = true;
}
slideshow.prevEvent();
slideshow.nextEvent();
}
run();
/*如果您的页面使用的是 rem 单位,请解开以下注释,同时注释上一行run();*/
// let initInterval = setInterval(function () {
// let remV = parseFloat(document.documentElement.style.fontSize);
// if (remV != NaN){
// window.clearInterval(initInterval);
// initInterval = null;
// } else {
// return;
// }
// if(initInterval != null){
// slideshow.intervals.push(initInterval);
// }
// slideshow.width = slideshow.defaultWidth/16*remV;
// run();
// },100);
},
//离开页面时调用
destroy:function () {
for(let i = 0;i<slideshow.intervals.length;i++){
window.clearInterval(slideshow.intervals[i]);
}
}
}
/*如果您使用的vue,请解开以下注释 */
// export {
// slideshow
// }
这个插件怎么用呢,首先引入到html页面。
然后进行轮播图的布局。
布局采用的是大家常见的 无缝滚动轮播图。
HTML布局:
<div class="slide-box">
<span class="prev"></span>
<div class="hot">
<ul>
<li style="background-color: gray;">
轮播图1
</li>
<li style="background-color: hotpink;">
轮播图2
</li>
<li style="background-color: #008c8c;">
轮播图3
</li>
</ul>
</div>
<span class="next"></span>
</div>
CSS样式:
css样式是需要根据实际情况调整的
.slide-box {
width: 1325px;
height: 221px;
margin: 66px auto 0;
position: relative;
}
.slide-box .prev,
.slide-box .next {
display: block;
width: 23px;
height: 39px;
position: absolute;
top: 91px;
cursor: pointer;
}
.slide-box .prev {
/*background-image: url('../../assets/img/profile/zuo.png');
background-size: 100% 100%;*/
background-color: hotpink;
left: -53px;
}
.slide-box .next {
/*background-image: url('../../assets/img/profile/you.png');
background-size: 100% 100%;*/
background-color: blue;
right: -53px;
}
.slide-box .hot {
width: 1325px;
height: 221px;
overflow: hidden;
}
.slide-box .hot ul {
width: 3975px;
height: 221px;
position: relative;
}
.slide-box ul li {
width: 1325px;
height: 221px;
float: left;
font-size: 80px;
list-style: none;
}
最后就是调用了,如果你使用的是vue,你可以这样:
import {slideshow} from './slideshow';
export default {
data() {
return {
}
},
components: {
},
mounted() {
slideshow.init();
},
beforeDestroy(){
slideshow.destroy();
},
created() {
}
}
//同时注意解开前面slideshow.js里的相应注释
如果你使用的原生html,直接调用:
window.onload = function () {
slideshow.init();
};
看看效果: