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的大概結(jié)構(gòu):
<div id="container">
<!-- 這里必須要定位list的left位置為0px -->
<div id="list" style="left: 0px;">





</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>
輪播之箭頭切換 & 無限滾動(dòng) 的實(shí)現(xiàn):
代碼如下:
window.onload = function() {
// 獲取最外層容器container
var container = document.getElementById('container');
// 獲取包裹圖片的list容器
var list = document.getElementById('list');
// 獲取包裹橙點(diǎn)的span
var buttons = document.getElementById('buttons').getElementsByTagName('span');
var prev = document.getElementById('prev');
var next = document.getElementById('next');
/**
* [animate: 箭頭控制圖片位置函數(shù)]
* @param {[number]} offset [位移的數(shù)字]
*/
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);
}
}
上面的效果完成之后,會(huì)有一個(gè)問題,就是最下面的原點(diǎn)不會(huì)隨著圖片的變化,而當(dāng)前高亮刁愿。解決方案:
index為當(dāng)前原點(diǎn)span
中的的索引,并且我們要清楚之前的高亮的樣式到逊。
代碼如下:
var index = 1;
/**
* [showButton 下面的小圓點(diǎn)按鈕]
*/
function showButton() {
// 遍歷清除重復(fù)的原點(diǎn)樣式
for (var i = 0; i < buttons.length; i++) {
if (buttons[i].className == 'on') {
buttons[i].className = '';
break;
}
}
// 取到的button是從0開始計(jì)數(shù)的铣口,但是我們定義的index的初試是從1開始,故要減去1
buttons[index - 1].className = 'on';
}
但是到了這里觉壶,會(huì)有一個(gè)小問題脑题,就是當(dāng)我們點(diǎn)擊上面的左右箭頭滑動(dòng)到第一張圖片和最后一張圖片所對應(yīng)的原點(diǎn)的時(shí)候,我們再往前或者往后的時(shí)候铜靶,就不能正常高亮當(dāng)前原點(diǎn)了叔遂。
造成這種現(xiàn)象的主要原因是因?yàn)椋何覀兌x了index,并且隨著pre,和next的點(diǎn)擊,它會(huì)一直增加或者減少争剿,已經(jīng)為0的時(shí)候再減就變成了負(fù)數(shù)了已艰,已經(jīng)為4(對應(yīng)第五張圖)的時(shí)候,還是會(huì)繼續(xù)增加變成5。然而我們圓點(diǎn)對應(yīng)的span
的索引只有1到5蚕苇,所以這里我們還應(yīng)該對臨界的兩個(gè)span做一下判斷哩掺。
代碼如下:
next.onclick = function() {
if (index == 5) { // 如果到了最后一個(gè)圓點(diǎn)
index = 1; // 將index置1
}
else {
index += 1; // 只要不是最后一個(gè)則加1
}
showButton(); // 原代碼不變
animate(-600); // 原代碼不變
}
prev.onclick = function() {
if (index == 1) { //如果已經(jīng)到了第一個(gè)圓點(diǎn)
index = 5; // 直接跳到最后一個(gè)
}
else {
index -= 1; // 否則可以繼續(xù)累減
}
showButton(); // 原代碼不變
animate(600); // 原代碼不變
}
經(jīng)過上面的步驟,此時(shí)的代碼如下:
window.onload = function() {
// 獲取最外層容器container
var container = document.getElementById('container');
// 獲取包裹圖片的list容器
var list = document.getElementById('list');
// 獲取包裹橙點(diǎn)的span
var buttons = document.getElementById('buttons').getElementsByTagName('span');
var prev = document.getElementById('prev');
var next = document.getElementById('next');
var index = 1;
/**
* [showButton 下面的小圓點(diǎn)按鈕]
*/
function showButton() {
// 遍歷清除重復(fù)的原點(diǎn)樣式
for (var i = 0; i < buttons.length; i++) {
if (buttons[i].className == 'on') {
buttons[i].className = '';
break;
}
}
buttons[index - 1].className = 'on';
}
/**
* [animate: 箭頭控制圖片位置函數(shù)]
* @param {[number]} offset [位移的數(shù)字]
*/
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);
}
}
實(shí)現(xiàn)點(diǎn)擊下方圓點(diǎn)點(diǎn)擊更新對應(yīng)的圖片
for (var i = 0; i < buttons.length; i++) {
buttons[i].onclick = function() {
// 獲取當(dāng)前的index屬性里面的數(shù)字
var myIndex = parseInt(this.getAttribute('index'));
// 計(jì)算出圖片要移動(dòng)的距離
var offset = -600 * (myIndex - index);
animate(offset); //調(diào)用animate函數(shù)
index = myIndex; // 更新index的值
showButton(); //調(diào)用函數(shù)使得當(dāng)前圓點(diǎn)高亮
}
}
雖然以上的函數(shù)已經(jīng)可以實(shí)現(xiàn)功能了涩笤,但是嚼吞,如果我們點(diǎn)擊的按鈕是同一個(gè)盒件,也就是不變,按照上面的函數(shù)舱禽,for循環(huán)還是會(huì)被重新執(zhí)行一次炒刁。所以我們可以在點(diǎn)擊事件里加上一個(gè)if判斷。
代碼如下:
for (var i = 0; i < buttons.length; i++) {
buttons[i].onclick = function() {
if (this.className == 'on') { // 如果點(diǎn)擊的原點(diǎn)已經(jīng)高亮
return; // 直接return呢蔫,下面的代碼也不執(zhí)行了
}
var myIndex = parseInt(this.getAttribute('index'));
var offset = -600 * (myIndex - index);
animate(offset);
index = myIndex;
showButton();
}
}
PS:
下面這個(gè)函數(shù)切心,能夠獲取一個(gè)元素的任意 CSS 屬性值。
function getStyle(element, attr) {
if(element.currentStyle) {
return element.currentStyle[attr];
} else {
return getComputedStyle(element, false)[attr];
}
}
// 比如片吊,本例中如果想獲得 lists 的 left 屬性值,只需要 getStyle(lists,"left")就可以啦协屡。
加上定時(shí)器:
window.onload = function() {
// 獲取最外層容器container
var container = document.getElementById('container');
// 獲取包裹圖片的list容器
var list = document.getElementById('list');
// 獲取包裹橙點(diǎn)的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 下面的小圓點(diǎn)按鈕]
*/
function showButton() {
// 遍歷清除重復(fù)的原點(diǎn)樣式
for (var i = 0; i < buttons.length; i++) {
if (buttons[i].className == 'on') {
buttons[i].className = '';
break;
}
}
buttons[index - 1].className = 'on';
}
/**
* [animate: 控制圖片位置函數(shù)]
* @param {[number]} offset [位移的數(shù)字]
*/
function animate(offset) {
animated = true;
// 用newLeft存放加上傳入offset需要改變的新的left值
var newLeft = parseInt(list.style.left) + offset;
var time = 300; // 位移總時(shí)間
var interval = 10; // 位移間隔時(shí)間
var speed = offset / (time / interval); // 每次位移量
/**
* [go:位移的判斷以及什么時(shí)候做位移]
*/
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);
}
}
// 實(shí)現(xiàn)點(diǎn)擊下面的按鈕俏脊,圖片也跟著變換
// 遍歷所有的圓點(diǎn),給他們一個(gè)點(diǎn)擊事件
for (var i = 0; i < buttons.length; i++) {
buttons[i].onclick = function() {
if (this.className == 'on') { // 如果點(diǎn)擊的原點(diǎn)已經(jīng)高亮
return; // 直接return肤晓,下面的代碼也不執(zhí)行了
}
// 獲取當(dāng)前的index屬性里面的數(shù)字
var myIndex = parseInt(this.getAttribute('index'));
// 計(jì)算出圖片要移動(dòng)的距離
var offset = -600 * (myIndex - index);
if (!animated) {
animate(offset); //調(diào)用animate函數(shù)
}
index = myIndex; // 更新index的值
showButton(); //調(diào)用函數(shù)使得當(dāng)前圓點(diǎn)高亮
}
}
}
加上自動(dòng)播放函數(shù):
window.onload = function() {
// 獲取最外層容器container
var container = document.getElementById('container');
// 獲取包裹圖片的list容器
var list = document.getElementById('list');
// 獲取包裹橙點(diǎn)的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; //存放定時(shí)器
/**
* [showButton 下面的小圓點(diǎn)按鈕]
*/
function showButton() {
// 遍歷清除重復(fù)的原點(diǎn)樣式
for (var i = 0; i < buttons.length; i++) {
if (buttons[i].className == 'on') {
buttons[i].className = '';
break;
}
}
buttons[index - 1].className = 'on';
}
/**
* [animate: 控制圖片位置函數(shù)]
* @param {[number]} offset [位移的數(shù)字]
*/
function animate(offset) {
animated = true;
// 用newLeft存放加上傳入offset需要改變的新的left值
var newLeft = parseInt(list.style.left) + offset;
var time = 300; // 位移總時(shí)間
var interval = 10; // 位移間隔時(shí)間
var speed = offset / (time / interval); // 每次位移量
/**
* [go:位移的判斷以及什么時(shí)候做位移]
*/
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);
}
}
// 實(shí)現(xiàn)點(diǎn)擊下面的按鈕爷贫,圖片也跟著變換
// 遍歷所有的圓點(diǎn),給他們一個(gè)點(diǎn)擊事件
for (var i = 0; i < buttons.length; i++) {
buttons[i].onclick = function() {
if (this.className == 'on') { // 如果點(diǎn)擊的原點(diǎn)已經(jīng)高亮
return; // 直接return补憾,下面的代碼也不執(zhí)行了
}
// 獲取當(dāng)前的index屬性里面的數(shù)字
var myIndex = parseInt(this.getAttribute('index'));
// 計(jì)算出圖片要移動(dòng)的距離
var offset = -600 * (myIndex - index);
if (!animated) {
animate(offset); //調(diào)用animate函數(shù)
}
index = myIndex; // 更新index的值
showButton(); //調(diào)用函數(shù)使得當(dāng)前圓點(diǎn)高亮
}
}
container.onmouseover = stop;
container.onmouseout = play;
play();
}