demo效果:
css布局:
* {
margin: 0;
padding: 0;
text-decoration: none;
}
body {
padding: 20px;
}
#container {
width: 600px;
height: 400px;
border: 3px solide #333;
overflow: hidden;
position: relative;
}
#list {
background-color: red;
width: 3000px; /* 7*600 = 4200px */
height: 400px; /*一共有七张图(600*400)*/
position: absolute;
z-index: 1;
}
#list img {
float: left;
}
#buttons {
position: absolute;
height: 10px;
width: 100px;
z-index: 2;
bottom: 20px;
left: 250px;
}
#buttons span {
cursor: pointer;
float: left;
border: 1px solid #fff;
width: 10px;
height: 10px;
border-radius: 50%;
background: #333;
margin-right: 5px;
}
#buttons .on {
background: orangered;
}
.arrow {
cursor: pointer;
display: none;
line-height: 39px;
text-align: center;
font-size: 36px;
font-weight: bold;
width: 40px;
height: 40px;
position: absolute;
z-index: 2;
top: 180px;
background-color: rgba(0, 0, 0, .3);
color: #fff;
}
.arrow:hover {
background-color: rgba(0, 0, 0, .7);
}
#container:hover .arrow {
display: block;
}
#prev {
left: 20px;
}
#next {
right: 20px;
}
其次html的大概结构:
<div id="container">
<!-- 这里必须要定位list的left位置为0px -->
<div id="list" style="left: 0px;">
![](img/1.jpg)
![](img/2.jpg)
![](img/3.jpg)
![](img/4.jpg)
![](img/5.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>
</div>
<a href="javascript:;" id="prev" class="arrow"><</a>
<a href="javascript:;" id="next" class="arrow">></a>
</div>
轮播之箭头切换 & 无限滚动 的实现:
代码如下:
window.onload = function() {
// 获取最外层容器container
var container = document.getElementById('container');
// 获取包裹图片的list容器
var list = document.getElementById('list');
// 获取包裹橙点的span
var buttons = document.getElementById('buttons').getElementsByTagName('span');
var prev = document.getElementById('prev');
var next = document.getElementById('next');
/**
* [animate: 箭头控制图片位置函数]
* @param {[number]} offset [位移的数字]
*/
function animate(offset) {
// 用newLeft存放加上传入offset需要改变的新的left值
var newLeft = parseInt(list.style.left) + offset;
list.style.left = newLeft + 'px';
if (newLeft > 0) {
list.style.left = -2400 + 'px';
}
if (newLeft < -2400) {
list.style.left = 0 + 'px';
}
}
next.onclick = function() {
animate(-600);
}
prev.onclick = function() {
animate(600);
}
}
上面的效果完成之后,会有一个问题,就是最下面的原点不会随着图片的变化,而当前高亮。解决方案:
index为当前原点span
中的的索引,并且我们要清楚之前的高亮的样式。
代码如下:
var index = 1;
/**
* [showButton 下面的小圆点按钮]
*/
function showButton() {
// 遍历清除重复的原点样式
for (var i = 0; i < buttons.length; i++) {
if (buttons[i].className == 'on') {
buttons[i].className = '';
break;
}
}
// 取到的button是从0开始计数的,但是我们定义的index的初试是从1开始,故要减去1
buttons[index - 1].className = 'on';
}
但是到了这里,会有一个小问题,就是当我们点击上面的左右箭头滑动到第一张图片和最后一张图片所对应的原点的时候,我们再往前或者往后的时候,就不能正常高亮当前原点了。
造成这种现象的主要原因是因为:我们定义了index,并且随着pre,和next的点击,它会一直增加或者减少,已经为0的时候再减就变成了负数了,已经为4(对应第五张图)的时候,还是会继续增加变成5。然而我们圆点对应的span
的索引只有1到5,所以这里我们还应该对临界的两个span做一下判断。
代码如下:
next.onclick = function() {
if (index == 5) { // 如果到了最后一个圆点
index = 1; // 将index置1
}
else {
index += 1; // 只要不是最后一个则加1
}
showButton(); // 原代码不变
animate(-600); // 原代码不变
}
prev.onclick = function() {
if (index == 1) { //如果已经到了第一个圆点
index = 5; // 直接跳到最后一个
}
else {
index -= 1; // 否则可以继续累减
}
showButton(); // 原代码不变
animate(600); // 原代码不变
}
经过上面的步骤,此时的代码如下:
window.onload = function() {
// 获取最外层容器container
var container = document.getElementById('container');
// 获取包裹图片的list容器
var list = document.getElementById('list');
// 获取包裹橙点的span
var buttons = document.getElementById('buttons').getElementsByTagName('span');
var prev = document.getElementById('prev');
var next = document.getElementById('next');
var index = 1;
/**
* [showButton 下面的小圆点按钮]
*/
function showButton() {
// 遍历清除重复的原点样式
for (var i = 0; i < buttons.length; i++) {
if (buttons[i].className == 'on') {
buttons[i].className = '';
break;
}
}
buttons[index - 1].className = 'on';
}
/**
* [animate: 箭头控制图片位置函数]
* @param {[number]} offset [位移的数字]
*/
function animate(offset) {
// 用newLeft存放加上传入offset需要改变的新的left值
var newLeft = parseInt(list.style.left) + offset;
list.style.left = newLeft + 'px';
if (newLeft > 0) {
list.style.left = -2400 + 'px';
}
if (newLeft < -2400) {
list.style.left = 0 + 'px';
}
}
next.onclick = function() {
if (index == 5) {
index = 1;
}
else {
index += 1;
}
showButton();
animate(-600);
}
prev.onclick = function() {
if (index == 1) {
index = 5;
}
else {
index -= 1;
}
showButton();
animate(600);
}
}
实现点击下方圆点点击更新对应的图片
for (var i = 0; i < buttons.length; i++) {
buttons[i].onclick = function() {
// 获取当前的index属性里面的数字
var myIndex = parseInt(this.getAttribute('index'));
// 计算出图片要移动的距离
var offset = -600 * (myIndex - index);
animate(offset); //调用animate函数
index = myIndex; // 更新index的值
showButton(); //调用函数使得当前圆点高亮
}
}
虽然以上的函数已经可以实现功能了,但是,如果我们点击的按钮是同一个,也就是不变,按照上面的函数,for循环还是会被重新执行一次。所以我们可以在点击事件里加上一个if判断。
代码如下:
for (var i = 0; i < buttons.length; i++) {
buttons[i].onclick = function() {
if (this.className == 'on') { // 如果点击的原点已经高亮
return; // 直接return,下面的代码也不执行了
}
var myIndex = parseInt(this.getAttribute('index'));
var offset = -600 * (myIndex - index);
animate(offset);
index = myIndex;
showButton();
}
}
PS:
下面这个函数,能够获取一个元素的任意 CSS 属性值。
function getStyle(element, attr) {
if(element.currentStyle) {
return element.currentStyle[attr];
} else {
return getComputedStyle(element, false)[attr];
}
}
// 比如,本例中如果想获得 lists 的 left 属性值,只需要 getStyle(lists,"left")就可以啦。
加上定时器:
window.onload = function() {
// 获取最外层容器container
var container = document.getElementById('container');
// 获取包裹图片的list容器
var list = document.getElementById('list');
// 获取包裹橙点的span
var buttons = document.getElementById('buttons').getElementsByTagName('span');
var prev = document.getElementById('prev');
var next = document.getElementById('next');
var index = 1;
var animated = false;
/**
* [showButton 下面的小圆点按钮]
*/
function showButton() {
// 遍历清除重复的原点样式
for (var i = 0; i < buttons.length; i++) {
if (buttons[i].className == 'on') {
buttons[i].className = '';
break;
}
}
buttons[index - 1].className = 'on';
}
/**
* [animate: 控制图片位置函数]
* @param {[number]} offset [位移的数字]
*/
function animate(offset) {
animated = true;
// 用newLeft存放加上传入offset需要改变的新的left值
var newLeft = parseInt(list.style.left) + offset;
var time = 300; // 位移总时间
var interval = 10; // 位移间隔时间
var speed = offset / (time / interval); // 每次位移量
/**
* [go:位移的判断以及什么时候做位移]
*/
function go() {
if ((speed > 0 && parseInt(list.style.left) < newLeft)
|| (speed < 0 && parseInt(list.style.left) > newLeft)) {
list.style.left = parseInt(list.style.left) + speed + 'px';
setTimeout(go, interval); // 递归
}
else {
animated = false;
list.style.left = newLeft + 'px';
if (newLeft > 0) {
list.style.left = -2400 + 'px';
}
if (newLeft < -2400) {
list.style.left = 0 + 'px';
}
}
}
go();
}
next.onclick = function() {
if (index == 5) {
index = 1;
}
else {
index += 1;
}
showButton();
if (!animated) {
animate(-600);
}
}
prev.onclick = function() {
if (index == 1) {
index = 5;
}
else {
index -= 1;
}
showButton();
if (!animated) {
animate(600);
}
}
// 实现点击下面的按钮,图片也跟着变换
// 遍历所有的圆点,给他们一个点击事件
for (var i = 0; i < buttons.length; i++) {
buttons[i].onclick = function() {
if (this.className == 'on') { // 如果点击的原点已经高亮
return; // 直接return,下面的代码也不执行了
}
// 获取当前的index属性里面的数字
var myIndex = parseInt(this.getAttribute('index'));
// 计算出图片要移动的距离
var offset = -600 * (myIndex - index);
if (!animated) {
animate(offset); //调用animate函数
}
index = myIndex; // 更新index的值
showButton(); //调用函数使得当前圆点高亮
}
}
}
加上自动播放函数:
window.onload = function() {
// 获取最外层容器container
var container = document.getElementById('container');
// 获取包裹图片的list容器
var list = document.getElementById('list');
// 获取包裹橙点的span
var buttons = document.getElementById('buttons').getElementsByTagName('span');
var prev = document.getElementById('prev');
var next = document.getElementById('next');
var index = 1;
var animated = false;
var timer; //存放定时器
/**
* [showButton 下面的小圆点按钮]
*/
function showButton() {
// 遍历清除重复的原点样式
for (var i = 0; i < buttons.length; i++) {
if (buttons[i].className == 'on') {
buttons[i].className = '';
break;
}
}
buttons[index - 1].className = 'on';
}
/**
* [animate: 控制图片位置函数]
* @param {[number]} offset [位移的数字]
*/
function animate(offset) {
animated = true;
// 用newLeft存放加上传入offset需要改变的新的left值
var newLeft = parseInt(list.style.left) + offset;
var time = 300; // 位移总时间
var interval = 10; // 位移间隔时间
var speed = offset / (time / interval); // 每次位移量
/**
* [go:位移的判断以及什么时候做位移]
*/
function go() {
if ((speed > 0 && parseInt(list.style.left) < newLeft)
|| (speed < 0 && parseInt(list.style.left) > newLeft)) {
list.style.left = parseInt(list.style.left) + speed + 'px';
setTimeout(go, interval); // 递归
}
else {
animated = false;
list.style.left = newLeft + 'px';
if (newLeft > 0) {
list.style.left = -2400 + 'px';
}
if (newLeft < -2400) {
list.style.left = 0 + 'px';
}
}
}
go();
}
function play() {
timer = setInterval(function() {
next.onclick();
}, 3000);
}
function stop() {
clearInterval(timer);
}
next.onclick = function() {
if (index == 5) {
index = 1;
}
else {
index += 1;
}
showButton();
if (!animated) {
animate(-600);
}
}
prev.onclick = function() {
if (index == 1) {
index = 5;
}
else {
index -= 1;
}
showButton();
if (!animated) {
animate(600);
}
}
// 实现点击下面的按钮,图片也跟着变换
// 遍历所有的圆点,给他们一个点击事件
for (var i = 0; i < buttons.length; i++) {
buttons[i].onclick = function() {
if (this.className == 'on') { // 如果点击的原点已经高亮
return; // 直接return,下面的代码也不执行了
}
// 获取当前的index属性里面的数字
var myIndex = parseInt(this.getAttribute('index'));
// 计算出图片要移动的距离
var offset = -600 * (myIndex - index);
if (!animated) {
animate(offset); //调用animate函数
}
index = myIndex; // 更新index的值
showButton(); //调用函数使得当前圆点高亮
}
}
container.onmouseover = stop;
container.onmouseout = play;
play();
}