轮播图简单实现
如何实现轮播图?
根据视频尚硅谷JavaScript视频整理得到。
思路:
ul是将所有图片平铺,不断改变ul的left属性,使得图片得以轮转
div可以设置属性:overflow:hidden 是超出div范围的图片隐藏
创建静态界面:
<style>
*{
margin: 0;
padding: 0;
}
#outer{
background-color: aquamarine;
height: 332px;
margin: 50px auto;
overflow: hidden;
position: relative;
width: 520px;
padding: 10px 0px;
}
#imgList{
/*width写死了不好*/
/*width: 2500px;*/
/*去除项目符号*/
list-style: none;
position: absolute;
left: -520px;
/*每向左移动530,到下面一张图*/
}
#imgList li{
float: left;
margin: 0 10px;
}
#navDiv{
position: absolute;
bottom: 5px;
/*left可以利用js设定*/
/*left=(outerWidth-navDivWidth)/2*/
}
#navDiv a{
float: left;
width: 10px;
height: 10px;
background-color: cadetblue;
margin-left:5px;
opacity: 0.7;
/*兼容IE8*/
filter: alpha(opacity=70);
}
#navDiv a:hover{
background-color: yellow;
}
</style>
<body>
<div>
<div id="outer">
<ul id="imgList">
<li>
<img src="img/1.jpg">
</li>
<li>
<img src="img/2.jpg">
</li>
<li>
<img src="img/3.jpg">
</li>
<li>
<img src="img/4.jpeg">
</li>
</ul>
<div id="navDiv">
<a href="javascript:;"></a>
<a href="javascript:;"></a>
<a href="javascript:;"></a>
<a href="javascript:;"></a>
</div>
</div>
</div>
</body>
静态界面创建成功界面如下:
这里注意imgList(ul)的长度和navDiv(超链接)的位置没有通过CSS静态设置,通过JS动态设置可以方便后续添加图片
//设置ul宽度
var imgList = document.getElementById("imgList");
var imgArr = document.getElementsByTagName("img");
// 图片长度加上margin的长度
imgList.style.width = 530 * imgArr.length + "px";
//设置下面导航小点的位置
// 父级元素div的长度减去小点的长度
var outer = document.getElementById("outer");
var navDir = document.getElementById("navDiv");
navDir.style.left = (outer.offsetWidth - navDir.offsetWidth) / 2 + "px";
// 默认初始索引为0
var index = 0;
var allA = document.getElementsByTagName("a");
allA[index].style.backgroundColor = "yellow";
通过上面的代码,静态页面显示完毕,下面是添加JS代码使得图片轮播起来
点击导航栏(超链接)使得图片可以切换图片
//点击不同的超链接,切换到不同的图片
for (var i = 0; i < allA.length; i++) {
//为每一个超链接添加num属性
allA[i].num = i;
allA[i].onclick = function () {
index = this.num;
//切换图片
//第一张 0 0 第二张 1 -520
//静态改变图片
imgList.style.left = index * -520 +"px"
//修改超链接
setA();
}
}
这里是静态改变ul的left属性值,使得图片可以切换但是并未达到轮播效果。
下面是用超链接的颜色改变,写在setA()函数里面,在上面的代码中进行调用,实现点击不同的超链接,出现相应的图片并且颜色出现变化。
这里注意:allA[i].style.backgroundColor = “”设置为空串的原因是,js设置的样式为内联样式,会覆盖掉之前在CSS样式表里面设置的样式,使得hover失效,所以这里使用空串,在遍历后,颜色不发生变化,只是在index中设置变化后的样式,hover有效。。
//创建方法使得点击的超链接变色其他的不变
function setA() {
for (var i = 0; i < allA.length; i++) {
// 将所有的遍历背景颜色设置为本色
// 这样写会使得hover失效,内联样式会覆盖样式表的样式
// allA[i].style.backgroundColor = "cadetblue";
// 写成空串就不会覆盖
allA[i].style.backgroundColor = ""
}
// 将选中的超链接变色
allA[index].style.backgroundColor = "yellow";
}
添加计数器使得图片轮播,修改步骤一的函数,现在点击导航栏可以实现图片轮播
这里要介绍视频之前写的一个很方便的元素移动的函数// 获取当前元素的位置
function getstyle(obj, name) {
if (window.getComputedStyle) {
return getComputedStyle(obj, null)[name];
} else {
return obj.currentScript[name];
}
}
// 元素移动函数
// obj:移动元素
// target:移动范围目标位置
// speed:移动速度(正负)
// direction:移动方向
// callback:回调函数,动画执行完毕后执行
function move(obj, target, speed, direction,callback) {
clearInterval(obj.timer);
var current = parseInt(getstyle(obj, direction));
if (current > target) {
speed = -speed;
}
obj.timer = setInterval(function () {
var oldValue = parseInt(getstyle(obj, direction));
var newValue = oldValue + speed;
if ((speed < 0 && newValue < target) || (speed > 0 && newValue > target)) {
newValue = target;
}
obj.style[direction] = newValue + "px";
if (newValue == target) {
clearInterval(obj.timer);
callback();
}
}, 30);
}
move()可以将代码全部复制过去,添加元素,目标位置,方向,速度,回调函数,在调用函数,即可实现。逻辑很简单:获取元素当前位置,在当前位置上进行相应的改变。其中的direction其实不完全是方向,可以设置为left,top,width,height都可以。
修改第二步的静态切换图片的方法
注释掉imgList.style.left = index * -520 +“px”,调用move函数,回调函数暂时空着,调用setA()函数改变导航栏(超链接)
//静态改变图片
// imgList.style.left = index * -520 +"px"
//加上计时器
move(imgList, -520 * index, 10, "left",function () {
});
//修改超链接
// this.style.backgroundColor = "yellow";
setA();
实现图片自动轮播
index实现自增,开启计时器,调用move()函数实现图片自动轮播。
但是现在仍存在问题:- 在轮播到最后一张的时候,index自动为0,图片向第一张迅速移动,在最后一张的时候图片轮播不连续。
- 图片轮播的时候,超链接和图片不一致
- 图片自动轮播的动画和点击超链接图片切换动画会出现冲突
function auto() {
//开启计时器
setInterval(function () {
//索引自增
index++;
//判断index的值不能超过最大值
if (index == imgArr.length){
index = 0;
}
move(imgList,-520*index,10,"left",function () {
}
},3000)
}
auto()
解决图片轮播到最后一张向前跳跃问题
解决办法一 :在最后一张图片再添加第一张图片………
<li><img src="img/4.jpeg"></li>
<li><img src="img/1.jpg"></li>
结果:换汤不换药 ,图片在切换第二张的时候还是不连贯
解决办法二:在auto()函数添加if语句,在最后一张的时候,设置imgList.style.left=0;
结果:在倒数第一张向第一张切换的时候,没有出现动画,图片直接变化
将上面两种方法结合可以得到解决问题的办法
图解如下:
在最后一张的时候,由于后面仍有第一张,所以图片继续向后轮播,但是有imgList.style.left = 0;所以ul向前跳转,但是由于图片一样,造成连续切换的假象。这里可以将图片顺序改为最后一张图片接其他图片,就会发现中间的图片切换
.........
<li><img src="img/4.jpeg"></li>
<li><img src="img/2.jpg"></li>
在setA()的函数中添加
//判断索引是否为最后一张图片
if (index >= imgArr.length -1){
index = 0;
//此时显示最后一张但是和第一张一样
imgList.style.left = 0;
}
此时可以完美解决最后一张图片跳跃问题
解决自动轮播图片和超链接不匹配问题
这里就是在auto()函数中合理调用setA()的问题。由于auto()函数中实现图片轮播的函数是move()函数,如果在执行完move()函数结束后调用,会在最后一张图片跳转出现问题,无法播放我们放在最后一张图片后面的第一张图片,这样会造成问题4还是存在,并且此时回到第一张的时候index不等于0(注意此时由于加了一张图片imgArr会加一),回到第一张会向后轮播几张后再回到第二张;这时候我们需要用到move()的回调函数,这个实在动画轮播结束后迅速执行,每次转换到下一张时,导航随之变化,比较符合我们的问题,并且不会影响其他值的变化。(这里其实我也觉得很神奇,有点糊涂,讲道理放外面和放里面应该不会有什么区别啊????还得 在研究研究)//修改导航点
move(imgList,-520*index,10,"left",function () {
setA();
})
},3000)
解决点击点击导航栏切换图片动画和图片自动轮播动画冲突问题
点击事件优于自动轮播,所以让自动轮播的计时器等于一个变量,在触发超链接的点击事件,先关闭计时器,然后在移动到相应的图片后在调用auto函数,图片继续自动轮播。llA[i].onclick = function () {
clearInterval(timer);
index = this.num;
//切换图片
//第一张 0 0 第二张 1 -520
//静态改变图片
// imgList.style.left = index * -520 +"px"
//加上计时器
move(imgList, -520 * index, 10, "left",function () {
//动画执行完毕执行自动切换动画
auto();
});
所有代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
*{
margin: 0;
padding: 0;
}
#outer{
background-color: aquamarine;
height: 332px;
margin: 50px auto;
overflow: hidden;
position: relative;
width: 520px;
padding: 10px 0px;
}
#imgList{
/*width写死了不好*/
/*width: 2500px;*/
/*去除项目符号*/
list-style: none;
position: absolute;
/*每向左移动530,到下面一张图*/
}
#imgList li{
float: left;
margin: 0 10px;
}
#navDiv{
position: absolute;
bottom: 5px;
/*left可以利用js设定*/
/*left=(outerWidth-navDivWidth)/2*/
}
#navDiv a{
float: left;
width: 10px;
height: 10px;
background-color: cadetblue;
margin-left:5px;
opacity: 0.7;
/*兼容IE8*/
filter: alpha(opacity=70);
}
#navDiv a:hover{
background-color: yellow;
}
</style>
<script type="text/javascript">
window.onload = function () {
//设置ul宽度
var imgList = document.getElementById("imgList");
var imgArr = document.getElementsByTagName("img");
// 图片长度加上margin的长度
imgList.style.width = 530 * imgArr.length + "px";
//设置下面导航小点的位置
// 父级元素div的长度减去小点的长度
var outer = document.getElementById("outer");
var navDir = document.getElementById("navDiv");
navDir.style.left = (outer.offsetWidth - navDir.offsetWidth) / 2 + "px";
// 默认初始索引为0
var index = 0;
var allA = document.getElementsByTagName("a");
allA[index].style.backgroundColor = "yellow";
//点击不同的超链接,切换到不同的图片
for (var i = 0; i < allA.length; i++) {
//为每一个超链接添加num属性
allA[i].num = i;
allA[i].onclick = function () {
//关闭自动播放的计时器
clearInterval(timer);
index = this.num;
//切换图片
//第一张 0 0 第二张 1 -520
//静态改变图片
// imgList.style.left = index * -520 +"px"
//加上计时器
move(imgList, -520 * index, 10, "left",function () {
//动画执行完毕执行自动切换动画
auto();
});
//修改超链接
// this.style.backgroundColor = "yellow";
setA();
}
}
//创建方法使得点击的超链接变色其他的不变
function setA() {
//判断索引是否为最后一张图片
if (index >= imgArr.length -1){
index = 0;
//此时显示最后一张但是和第一张一样
imgList.style.left = 0;
}
for (var i = 0; i < allA.length; i++) {
// 将所有的遍历背景颜色设置为本色
// 这样写会使得hover失效,内联样式会覆盖样式表的样式
// allA[i].style.backgroundColor = "cadetblue";
// 写成空串就不会覆盖
allA[i].style.backgroundColor = ""
}
// 将选中的超链接变色
allA[index].style.backgroundColor = "yellow";
}
// 获取当前元素的位置
function getstyle(obj, name) {
if (window.getComputedStyle) {
return getComputedStyle(obj, null)[name];
} else {
return obj.currentScript[name];
}
}
//图片自动切换
var timer;
function auto() {
//开启计时器
timer = setInterval(function () {
//索引自增
index++;
//判断index的值不能超过最大值
if (index == imgArr.length){
index = 0;
}
//修改导航点
move(imgList,-520*index,10,"left",function () {
setA();
})
},3000)
}
auto()
// 点击链接切换图片
// obj:移动元素
// target:移动范围目标位置
// speed:移动速度(正负)
// direction:移动方向
// callback:回调函数,动画执行完毕后执行
function move(obj, target, speed, direction,callback) {
clearInterval(obj.timer);
var current = parseInt(getstyle(obj, direction));
if (current > target) {
speed = -speed;
}
obj.timer = setInterval(function () {
var oldValue = parseInt(getstyle(obj, direction));
var newValue = oldValue + speed;
if ((speed < 0 && newValue < target) || (speed > 0 && newValue > target)) {
newValue = target;
}
obj.style[direction] = newValue + "px";
if (newValue == target) {
clearInterval(obj.timer);
callback();
}
}, 30);
}
}
</script>
</head>
<body>
<div>
<div id="outer">
<ul id="imgList">
<li>
<img src="img/1.jpg">
</li>
<li>
<img src="img/2.jpg">
</li>
<li>
<img src="img/3.jpg">
</li>
<li>
<img src="img/4.jpeg">
</li>
<li>
<img src="img/1.jpg">
</li>
</ul>
<div id="navDiv">
<a href="javascript:;"></a>
<a href="javascript:;"></a>
<a href="javascript:;"></a>
<a href="javascript:;"></a>
</div>
</div>
</div>
</body>
</html>
还没有评论,来说两句吧...