使用原生JS实现轮播图,下面先看看成品;
实现的效果
- 图片自动滑动切换,鼠标移动到图片上则停止切换;
- 鼠标移动到圆点时切换到相应的图片;
- 点击箭头切换到下一张图片;
- 鼠标离开图片,则隐藏箭头;
- 默认是3张图片,需要更多图片时,只需追加
<img>标签;
实现逻辑
将图片连接成条形,像胶卷一样,给个图片大小的窗口,左右移动图片条,完成切换;
实现代码
HTML
基本的HTML框架
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>轮播图</title> <link rel="stylesheet" href="css/slide.css"> </head> <body> <div class="box"> <div id="pic_box"> <img src="img/arrow_left.png" id="arrow-left"> <img src="img/arrow_right.png" id="arrow-right"> <ul id="multi-circles"></ul> <div id="multi-images"> <img src="img/1.jpg"><img src="img/2.jpg"><img src="img/3.jpg"> </div> </div> </div> <script src="js/slide.js"></script> </body> </html>
|
CSS
使用绝对定位对各个元素布局。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62
| :root { --imageWidth: 800px; --imageHeight: 240px; --imageNum: 3; }
.box { margin: 0 auto; width: 800px; }
#pic_box { position: relative; width: var(--imageWidth); height: var(--imageHeight); overflow: hidden; }
#multi-circles { position: absolute; right: 30px; bottom: 10px; z-index: 2; }
#multi-circles li { width: 25px; list-style: none; font-size: 24px; float: left; color: white; }
#multi-images { position: absolute; left: 0; top: 0; z-index: 1; width: calc(var(--imageWidth) * var(--imageNum)); height: var(--imageHeight); transition: 1s; }
#arrow-right, #arrow-left { position: absolute; top: 50%; margin-top: -24px; height: 48px; z-index: 3; background: rgba(159, 180, 179, 0.38); display: none; cursor: pointer; }
#arrow-right { right: 0; }
#arrow-left { left: 0; }
|
JS
核心步骤:
- 获取图片个数。
- 添加圆点。
- 设置“图片条”长度。
- 添加圆点、箭头的鼠标与点击事件;
- 设置图片轮播定时器;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
| var arrowLeft = document.getElementById("arrow-left"); var arrowRight = document.getElementById("arrow-right"); var multiImages = document.getElementById("multi-images"); var circles = document.getElementById("multi-circles"); var picBox = document.getElementById("pic_box");
var picNum = multiImages.getElementsByTagName("img").length;
for (var i = 0; i < picNum; i++) { var liElement = document.createElement("li"); liElement.innerHTML = "●"; circles.appendChild(liElement); }
document.documentElement.style.setProperty("--imageNum", picNum);
var imageWidth = getComputedStyle(document.documentElement).getPropertyValue("--imageWidth"); imageWidth = imageWidth.substring(0, imageWidth.indexOf("px"));
multiImages.style.width = picNum * imageWidth + "px";
circles = document.getElementById("multi-circles").getElementsByTagName("li");
var maxIndex = picNum - 1;
var currentIndex = 0;
arrowLeft.addEventListener("click", preMove); arrowRight.addEventListener("click", nextMove); for (var i = 0; i < circles.length; i++) { circles[i].setAttribute("id", i); circles[i].addEventListener("mouseenter", overCircle); }
circles[0].style.color = "#ff0000";
var time = setInterval(nextMove, 2000);
function overCircle() { var preIndex = currentIndex; currentIndex = parseInt(this.id); moveImage(); changeCircleColor(preIndex, currentIndex) }
function preMove() { var preIndex = currentIndex; if (currentIndex !== 0) { currentIndex--; } else { currentIndex = maxIndex; } moveImage(); changeCircleColor(preIndex, currentIndex) }
function nextMove() { var preIndex = currentIndex; if (currentIndex !== maxIndex) { currentIndex++; } else { currentIndex = 0; } moveImage(); changeCircleColor(preIndex, currentIndex) }
function moveImage() { multiImages.style.left = -currentIndex * imageWidth + "px"; }
function changeCircleColor(preIndex, currentIndex) { circles[preIndex].style.color = "#ffffff"; circles[currentIndex].style.color = "#ff0000" }
picBox.addEventListener("mouseover", function (ev) { arrowRight.style.display = "block"; arrowLeft.style.display = "block"; clearInterval(time); });
picBox.addEventListener("mouseleave", function (ev) { arrowRight.style.display = "none"; arrowLeft.style.display = "none"; time = setInterval(nextMove, 2000); });
|
遇到的bug
- 第二张图片显示不完整,而且左边有白边,而第三张图片不显示。


在浏览器中检查发现两张图片之间有缝隙,导致第三张图片被强行换行,看起来第三张图片位置空白;尝试设置bored、margin、padding为0,并没有效果。看看HTML,看起来没什么问题;

解决办法:将<img>标签间的回车去掉,写成一行;或者将图片设置为左浮动,style="display:block; float:left";

原因:<img>标签是行内元素,默认排版为 inline-block;而所有的inline-block元素之间都会有空白。
- 在获取css文件中设置的图片宽高时,“获取”不到值;
使用document.documentElement.style.getPropertyValue("--imageWidth");得到的值为空;
解决办法:改用getComputedStyle(document.documentElement).getPropertyValue("--imageWidth");才能拿到:root选择器中设置的值;

原因:
document.documentElement.style.getPropertyValue只能获取内联式样的值;
而getComputedStyle(document.documentElement).getPropertyValue获取到的始终是实际的值;
注意事项
轮播图默认大小为800*240,图片大小一致时无需修改任何css、js;使用自定义大小的图片时需要修改css文件中:root中--imageWidth、--imageHeight的值;
参考链接
css变量赋值和取值的四种方式 原生JS实现滑动轮播图