原生 js 实现轮播图
一般而言轮播图都需要使用到动画效果,我这里是原生 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();};
看看效果: