不管是电商项目还是官网项目, 不管是 PC 端还是移动端, 我们最常见到的需求就是轮播图了实现轮播图的原理与设计模式有很多种, 网上也有很多成熟的轮播图插件, 如 swiper,Carousel 我先从京东商城下载了一些图片素材, 今天写一个简单的适合入门新手学的轮播图教程, 先来看一下轮播图实现的原理
轮播图原理:
轮播图的实现原理图. png
一组宽高相同的图平铺在一起, 容器大小与图片大小一致, 设置一个定时器, 通过计算偏移量来让图片进行滚动, 每次的偏移量刚好是一张图片的宽度, 也就是容器的宽度首尾各添置一张一样的图片, 是为了让一组播放完之后进行循环播放无缝衔接, 防止出现空白页的情况
html 代码:
先写一个容器, 用来展示轮播图容器里主要放我们要轮播的图片, 下面的圆点按钮, 以及左右的切换按钮
- <div id="container">
- <!-- 图片 -->
- <div id="list" style="left: -600px;">
- <img src="img/8.png" />
- <img src="img/1.jpg" />
- <img src="img/2.png" />
- <img src="img/3.png" />
- <img src="img/4.png" />
- <img src="img/5.png" />
- <img src="img/6.png" />
- <img src="img/7.png" />
- <img src="img/8.png" />
- <img src="img/1.jpg" />
- </div>
- <!-- 圆点按钮 -->
- <div id="buttons">
- <span index="1" class="on"></span>
- <span index="2"></span>
- <span index="3"></span>
- <span index="4"></span>
- <span index="5"></span>
- <span index="6"></span>
- <span index="7"></span>
- <span index="8"></span>
- </div>
- <!-- 左右切换按钮 -->
- <a href="javascript:;" id="prev" class="arrow"><</a>
- <a href="javascript:;" id="next" class="arrow">></a>
- </div>
CSS 代码:
设置容器的大小, 刚好展示一张图片, 其他的设为不可见圆点按扭和左右切换按钮按要求进行绝对定位, 设置成想要的样子
- * {
- margin: 0;
- padding: 0;
- text-decoration: none;
- }
- body {
- padding: 20px;
- }
- #container {
- position: relative;
- width: 600px;
- height: 400px;
- border: 1px solid #333;
- overflow: hidden;
- }
- #list {
- position: absolute;
- z-index: 1;
- width: 6600px;
- height: 400px;
- }
- #list img {
- float: left;
- width: 600px;
- height: 400px;
- }
- #buttons {
- position: absolute;
- left: 20px;
- bottom: 20px;
- z-index: 2;
- height: 10px;
- width: 140px;
- }
- #buttons span {
- float: left;
- margin-right: 5px;
- width: 10px;
- height: 10px;
- border: 1px solid #fff;
- border-radius: 50%;
- background: #333;
- cursor: pointer;
- }
- #buttons .on {
- background: orangered;
- }
- .arrow {
- position: absolute;
- top: 180px;
- z-index: 2;
- display: none;
- width: 40px;
- height: 40px;
- font-size: 24px;
- line-height: 39px;
- text-align: center;
- color: #fff;
- background-color: RGBA(0, 0, 0, .3);
- cursor: pointer;
- }
- .arrow:hover {
- background-color: RGBA(0, 0, 0, .7);
- }
- #container:hover .arrow {
- display: block;
- }
- #prev {
- left: 20px;
- }
- #next {
- right: 20px;
- }
布局完之后, 一个静态的页面效果就呈现出来了(如下图), 接下来要详细的分解 JS 代码, 让这个轮播图动起来
轮播图效果图. png
第一步: 先实现点击左右切换按钮实现切换图片的效果
- var list = document.getElementById('list');
- var prev = document.getElementById('prev');
- var next = document.getElementById('next');
- window.onload = function() {
- function animate(offset) {
- // 获取的是 style.left, 是相对左边获取距离, 所以第一张图后 style.left 都为负值,
- // 且 style.left 获取的是字符串, 需要用 parseInt()取整转化为数字
- var newLeft = parseInt(list.style.left) + offset;
- if (newLeft < -4800) {
- list.style.left = -600 + 'px';
- } else if (newLeft > -600) {
- list.style.left = -4800 + 'px';
- } else {
- list.style.left = newLeft + 'px';
- }
- }
- prev.onclick = function() {
- animate(600);
- }
- next.onclick = function() {
- animate( - 600);
- }
- }
- }
我们在利用偏移量 left, 当 left 的值小于 - 4800 的时候, 因为没有第九张图, 会出现空白因为是相对于左边获取的 left, 第一张就是 - 600, 所以大于 - 600 时也会出现空白, 所以在 animate 函数中, 要加一个判断当 left 值小于 - 4800 时, 让 left 的值等于 - 600(即从最后一张图跳到第一张图)当 left 值大于 - 600 时, 让 left 的值等于 - 4800(即从第一张图跳到最后一张图)
第二步: 让图片自动轮播
- var timer;
- function play() {
- timer = setInterval(function() {
- next.onclick()
- }, 1500)
- }
- play();
设置一个定时器, 让它每隔 1.5 秒触发一次下一张按钮的点击事件, 实现自动轮播的效果
第三步: 绑定鼠标事件, 即实现鼠标移到图片上, 停止轮播, 移走开始轮播效果
- function stop() {
- clearInterval(timer);
- }
- var container = document.getElementById('container');
- container.onmouseover = stop;
- container.onmouseout = play;
实现这个效果, 只要封装一个函数 stop(), 用来清空定时器然后绑定鼠标事件, onmouseover 时调用 stop()停止轮播, onmouseout 调用 play()继续轮播
第四步: 实现圆点按钮随着图片变化而变化
- var buttons = document.getElementById('buttons').getElementsByTagName('span');
- var index = 1;
- function buttonsShow() {
- // 这里需要清除之前的样式
- for (var i = 0; i < buttons.length; i++) {
- if (buttons[i].className == 'on') {
- buttons[i].className = '';
- }
- }
- // 数组从 0 开始, 故 index 需要 - 1
- buttons[index - 1].className = 'on';
- }
- prev.onclick = function() {
- index -= 1;
- if (index < 1) {
- index = 8;
- }
- buttonsShow();
- animate(600);
- }
- next.onclick = function() {
- // 由于上边定时器的作用, index 会一直递增下去, 我们只有 5 个小圆点, 所以需要做出判断
- index += 1;
- if (index > 8) {
- index = 1;
- }
- buttonsShow();
- animate( - 600);
- }
定义一个变量 index, 用来记高亮圆点按钮的位置分装一个函数, 用来增加某个圆点按钮的高亮状态, 移除掉其他圆点按钮的高亮状态, 以实现圆点按钮与图片变化进行绑定
第五步: 给圆点按钮生成点击事件, 点击相应的按钮切换成相应的图片
- for (var i = 0; i < buttons.length; i++) {
- buttons[i].onclick = function() {
- /* 偏移量获取: 这里获得鼠标移动到小圆点的位置, 用 this 把 index 绑定到对象 buttons[i]上, 去谷歌 this 的用法 */
- /* 由于这里的 index 是自定义属性, 需要用到 getAttribute()这个 DOM2 级方法, 去获取自定义 index 的属性 */
- var clickIndex = parseInt(this.getAttribute('index'));
- var offset = 600 * (index - clickIndex);
- animate(offset); // 存放鼠标点击后的位置, 用于小圆点的正常显示
- index = clickIndex;
- buttonsShow();
- }
- }
JS 完整代码:
- // 定义需要的全局变量和获取需要使用的元素节点
- var timer;
- var index = 1;
- var list = document.getElementById('list');
- var prev = document.getElementById('prev');
- var next = document.getElementById('next');
- var container = document.getElementById('container');
- var buttons = document.getElementById('buttons').getElementsByTagName('span');
- window.onload = function() {
- function animate(offset) {
- // 获取的是 style.left, 是相对左边获取距离, 所以第一张图后 style.left 都为负值,
- // 且 style.left 获取的是字符串, 需要用 parseInt()取整转化为数字
- var newLeft = parseInt(list.style.left) + offset;
- if (newLeft < -4800) {
- list.style.left = -600 + 'px';
- index = 1;
- } else if (newLeft > -600) {
- list.style.left = -4800 + 'px';
- index = 8;
- } else {
- list.style.left = newLeft + 'px';
- }
- buttonsShow();
- }
- // 左 (上一张) 切换按钮点击事件
- prev.onclick = function() {
- index -= 1;
- if (index < 1) {
- index = 8;
- }
- buttonsShow();
- animate(600);
- }
- // 右 (下一张) 切换按钮点击事件
- next.onclick = function() {
- index += 1;
- if (index > 8) {
- index = 1;
- }
- buttonsShow();
- animate( - 600);
- }
- // 圆点切换图片
- for (var i = 0; i < buttons.length; i++) {
- buttons[i].onclick = function() {
- /* 偏移量获取: 这里获得鼠标移动到小圆点的位置, 用 this 把 index 绑定到对象 buttons[i]上, 去谷歌 this 的用法 */
- /* 由于这里的 index 是自定义属性, 需要用到 getAttribute()这个 DOM2 级方法, 去获取自定义 index 的属性 */
- var clickIndex = parseInt(this.getAttribute('index'));
- var offset = 600 * (index - clickIndex);
- animate(offset); // 存放鼠标点击后的位置, 用于小圆点的正常显示
- index = clickIndex;
- buttonsShow();
- }
- }
- play();
- container.onmouseover = stop;
- container.onmouseout = play;
- }
- // 图片自动播放函数
- function play() {
- timer = setInterval(function() {
- next.onclick()
- },
- 1500)
- }
- // 图片暂停播放函数
- function stop() {
- clearInterval(timer);
- }
- // 圆点按钮高亮状态切换函数
- function buttonsShow() {
- // 这里需要清除之前的样式
- for (var i = 0; i < buttons.length; i++) {
- if (buttons[i].className == 'on') {
- buttons[i].className = '';
- }
- }
- // 数组从 0 开始, 故 index 需要 - 1
- buttons[index - 1].className = 'on';
- }
一个最简单的轮播图效果基本上已经实现了, 可以明显的看到图片切换的过程不是特别流畅, 那么这个问题可以通过改变透明度或者利用 CSS3 的动画属性来得到一个较大的改善, 有兴趣的同学可以去研究一些希望这篇文章能够帮助到一些初学的同学也希望大神们可以给出一些建议好及时改正
来源: http://www.jianshu.com/p/21541fa05dc5