效果
我们要实现的效果
- 轮播* 点击左右箭头可以进行切换* 点击分页器也可以进行切换* 当鼠标移到图片上时,停止轮播以下是实现好的效果
实现思路
左右运动版轮播图核心是“无缝切换”
- 控制wrapper的左右移动,每一次都是移动一张slide的大小「每个slide和container容器一般宽」{每次移动有动画效果->CSS3动画}* 把真实的第一张克隆一份放在末尾「原本三个真实图片,现在就有四个了」* 如果当前处于最后一张(克隆的第一张),我们还想继续向后切换,发现后面没有了,此时* 快速回到真实的第一张「无动画」,由于两张一模一样,所以看不出运动来* 接着运动到第二张* …图解
–
![](https://i-blog.csdnimg.cn/blog_migrate/7cbb2fa5d3ca234b627de337e8d89f18.png)
HTML
为了减少代码量,这里我们删掉不必要的东西,主体结构如以下代码所示
<body><div class="container" id="bannerBox"><!-- 轮播图 --><div class="wrapper"><!-- <div class="slide"><img src="images/banner01.png" alt=""></div><div class="slide"><img src="images/banner02.jpg" alt=""></div><div class="slide"><img src="images/banner03.png" alt=""></div><div class="slide"><img src="images/banner01.png" alt=""></div> --></div><!-- 分页器 --><div class="pagination"><!-- <span index="0" class="active"></span><span index="1"></span><span index="2"></span> --></div><!-- 导航按钮 --><div class="navigation prev"></div><div class="navigation next"></div></div><!-- IMPORT JS --><script src="js/index.js"></script>
</body>
CSS
这里我们注意几个点
- 轮播图wrapper是通过相对定位的方式放在container里的* 默认展示第一张图片* width是根据slide数量决定的{不要忘记克隆的这一张}* 每一次wrapper左右运动,都是改变left值,我们让其具备过渡动画效果css的代码实在是太多了,这里大家看上面的实例自己随便写一写就好,为了减少代码量,这里我们直接把它删掉
js
基础实现版本
思路
- 拿到所有要操作的内容* 最外层轮播图容器* 包裹所有图片的容器* 分页器容器* 分页器span标签集合* step记录当前展示这个slide的索引* autoTimer记录自动轮播的定时器* distance记录容器的宽度,也是每一次wrapper运动的距离* count记录slide的总数量(包含克隆这一张)* 实现自动轮播* 如果累加后的索引比最大索引都大,说明当前已经是末尾这一张(克隆)* 我们让其立即运动到真实第一张 & 再让其有动画效果的运动到第二张* 图片切换的动画效果及偏移量* 每次切换完成,同时控制焦点对齐* 分页器对齐* 基于事件委托实现容器中分页器点击切换* 点击分页器的焦点* 点击的这一项就是展示的这一项,则无需处理[不要忘记克隆的那个]* {展示的克隆的那项 但是焦点处于0 所以也不用做处理}* 分页器焦点对齐* 左右导航按钮左右切换* 点击左按钮* 到达左边界:立即蹦到最后一张(克隆),然后运动到倒数第二张* 分页器焦点对齐* 右按钮* 和自动轮播一样* 开启自动轮播 & 控制自动轮播的暂停/继续* 轮循定时器* 当鼠标点上去要清空轮播图* 当鼠标离开的时候要 把轮播定时器加上代码实现
(function () {let bannerBox = document.querySelector('#bannerBox'), wrapper = bannerBox.querySelector('.wrapper'),pagination = bannerBox.querySelector('.pagination'),paginationList = pagination.querySelectorAll('span');let step = 0,autoTimer = null,distance = bannerBox.offsetWidth,//容器的宽度count = 4;//包含克隆的哪一张 const autoMove = function autoMove() {step++;if (step >= count) {wrapper.style.transitionDuration = '0s';wrapper.style.left = '0px';step = 1;wrapper.offsetWidth;}wrapper.style.transitionDuration = '0.3s';wrapper.style.left = `${-step * distance}px`;paginationFocus();};const paginationFocus = function paginationFocus() {let temp = step;if (temp === count - 1) temp = 0;paginationList.forEach((item, index) => {if (index === temp) {item.className = 'active';return;}item.className = '';});};bannerBox.addEventListener('click', function (ev) {let target = ev.target,tarTag = target.tagName;tarClass = target.className;if (tarTag === "SPAN") {let index = +target.getAttribute('index');if ((index === step) || (step === count - 1 && index === 0)) return; step = index;wrapper.style.left = `${-step * distance}px`;paginationFocus();return;}if (tarTag === 'DIV' && tarClass.includes('navigation')) {if (tarClass.includes('prev')) {step--;if (step < 0) {wrapper.style.transitionDuration = '0s';wrapper.style.left = `${-(count - 1) * distance}px`;step = count - 2;wrapper.offsetWidth;}wrapper.style.transitionDuration = '0.3s';wrapper.style.left = `${-step * distance}px`;paginationFocus();return;}autoMove();}});autoTimer = setInterval(autoMove, 1000);bannerBox.onmouseenter = () => clearInterval(autoTimer);bannerBox.onmouseleave = () => autoTimer = setInterval(autoMove, 1000);
})();
这个版本的轮播图是通过js完成的,但是我们的工作中很少这么做,一般来说,我们用的都是动态绑定的方法,不会写死数据;这篇文章写给新手小白练手,方便深刻理解;
最后
为大家准备了一个前端资料包。包含54本,2.57G的前端相关电子书,《前端面试宝典(附答案和解析)》,难点、重点知识视频教程(全套)。
有需要的小伙伴,可以点击下方卡片领取,无偿分享