JavaScript Dom實現(xiàn)輪播圖原理和實例
想要制作一個輪播圖我們要先弄清楚他的原理,如何能讓圖片自右向左滑動?
讓我們想一想生活中有沒有類似的東西,比如電影膠片。
我們可以創(chuàng)建一個塊作為投影區(qū),創(chuàng)建一個列表作為底片并使其向左移動,達到輪播圖效果。

創(chuàng)建一個塊和列表
創(chuàng)建一個塊作為總的容器和顯示區(qū)域。
<div id="out"> <ul id="imgList"> <li><img src="pto/many.jpg" ></li> <li><img src="pto/hello.jpg" ></li> <li><img src="pto/timg.jpg" ></li> <li><img src="pto/zhenjing.jpg"></li> </ul> </div>
現(xiàn)在圖片豎著堆在一列,塊也不知道在哪里,那添加一點樣式
開啟定位并令其居中,并且讓塊大一點并添加背景好確定位置(本實驗圖片統(tǒng)一寬高比500*431,所以div寬高比520*451)
去掉列表默認樣式讓列表橫著顯示
*{
margin: 0;
padding: 0;
}
#out{
width:520px;
height:451px ;
background-color: #00bcd4;
position: relative;
margin: 50px auto;
/*overflow: hidden;*/
/*剪掉我們不需要的部分,為了方便調(diào)試注掉了*/
}
#imgList{
list-style: none;
position: absolute;
/* left: -520px; */
}
#imgList li{
float:left;
margin: 10px;
}
在嘗試浮動后圖片依舊是一列,是因為lu的寬度太小放不下,所以我們要擴大,但是我們不能直接決定他的寬度因為隨著圖片的增加,寬度應(yīng)不斷變大,于是我們用JavaScript來解決寬度
每增加一張圖片擴大520px寬度
window.onload=function () {
// 動態(tài)的ul長度
var imgList = document.getElementById("imgList");
var imgArr = document.getElementsByTagName("img");
imgList.style.width=520*imgArr.length+"px";
}//onload
現(xiàn)在,裝載圖片的膠片ul每向左偏移-520px就會更換一個圖片
導(dǎo)航欄
輪播圖會定時更換,但是有可能你的客戶剛剛被吸引就已經(jīng)更換圖片了,如果你想讓你的客戶干巴巴的瞪著圖片回來,你很可能失去她。
所以一個完整的輪播圖還需要一個能手動切換前后的按鈕或一個導(dǎo)航條。
我們這里用幾個超鏈接完成任務(wù)
<div id="navDiv"> <a href="javascript:;"></a> <a href="javascript:;"></a> <a href="javascript:;"></a> <a href="javascript:;"></a> </div>
ul在開啟絕對定位后脫離文檔流,現(xiàn)在我們的導(dǎo)航因為沒有內(nèi)容縮成一團擠在左上角
我們要讓每一個超聯(lián)接彼此分開,手動撐開空間,調(diào)整到靠下的位置,下方正中或靠右是比較好的選擇.
調(diào)整透明度降低導(dǎo)航對于人的吸引力,畢竟圖片才是主題。
而位置的調(diào)整為了便于擴充我們還是要用js來解決。
}
#navDiv{
position: absolute;
bottom: 15px;
}
#navDiv a{
float: left;
width: 15px;
height: 15px;
background-color: #89ff00;
margin: 0 5px;
opacity: 0.5;
}
//動態(tài)導(dǎo)航居中
var navDiv = document.getElementById("navDiv");
var out = document.getElementById("out");
//將縱向剩余距離分到導(dǎo)航左右達到居中效果
//不除以二就會變成右對齊
//不要忘了單位,嗯。??赡苤挥形視?
navDiv.style.left = (out.clientWidth - navDiv.clientWidth)/2+"px";
導(dǎo)航功能完善
一僅僅個15px大的方塊要給用戶怎樣的反饋?
當前圖片所處位置,當鼠標移動到導(dǎo)航是時要反饋信息告訴用戶我是可以點擊的,點擊導(dǎo)航能切換圖片。
#navDiv a:hover{
background-color: red;
/* 鼠標移入效果*/
/* 內(nèi)聯(lián)樣式的優(yōu)先級很高注意不要被覆蓋失效*/
}
//定位效果
var allA = document.getElementsByTagName("a");
var index = 0;
allA[index].style.backgroundColor="black";
//點擊導(dǎo)航效果
//使用塊級作用域let,不然i會是同一個數(shù)
for(let i=0;i<allA.length;i++){
allA[i].onclick=function () {
imgList.style.left=-520*i+"px";
//清除內(nèi)聯(lián)樣式,使得css文件能生效
allA[index].style.backgroundColor="";
index=i;
allA[index].style.backgroundColor="black";
}
}
動畫效果
為什么要做動畫? (因為很酷(≧ω≦*)♪ )
因為沒有輪播效果不叫輪播圖,明明更改地址就能完成,忙活半天不就是為了這個,用最大的標題告訴你動畫才是輪播圖的精髓所在
主要思路是利用定時器讓本來一部完成的效果多次完成,到達指定位置關(guān)閉定時器。
要注意的問題
每次移動距離與圖片大小可能除余,導(dǎo)致停止位置不準確(大于或小于)或無法停止(不能剛好到達停止位置),小的誤差會逐漸積累。
在定時器打開前關(guān)閉上一個計時器,否則在一個動畫未完成前點擊另一個會發(fā)生鬼畜現(xiàn)象
//點擊導(dǎo)航效果
for(let i=0;i<allA.length;i++){
allA[i].onclick=function () {
move(imgList,-520*i,10);
// imgList.style.left=-520*i+"px";
//換掉這個很low的過場
allA[index].style.backgroundColor="";
index=i;
allA[index].style.backgroundColor="black";
}
}
function move(obj,target,speed) {//元素;目標位置;速度
//每次觸發(fā)事件關(guān)閉上一個定時器
//這里是重點,你可以去掉這一句后隨意點一下關(guān)差效果
clearInterval(obj.timer);
var current = parseInt(window.getComputedStyle(obj,null).left);
//獲得當前位置
//判斷運動方向
if(target<current){
speed = -speed;
}
//定時器標識
obj.timer = window.setInterval(function () {
//m每次開始獲取一下當前位置
var oldValue = parseInt(window.getComputedStyle(obj,null).left);
//移動并在指定位置停下
var newValue = oldValue + speed;
//調(diào)整一下停止位置,小的誤差會隨時間無限放大
if((speed < 0 && newValue < target)||(speed > 0 && newValue > target)){
newValue = target;
}
imgList.style.left =newValue+"px";
if(newValue == target){
clearInterval(obj.timer);
}
},30);
}
change();
//自動輪播
//一個定時器用于定時調(diào)用
function change() {
setInterval(function () {
index++;
index=index % imgArr.length ;
console.log(imgArr.length);
console.log(index);
move(imgList,-520*index,20);
for(let i=0;i<allA.length;i++){
allA[i].style.backgroundColor="";
allA[index].style.backgroundColor="black";
}
},3000);
}
這樣已經(jīng)能做到輪播的基本功能,但在最后一張圖片切換第一張圖片時會向左拉過全部圖片,這非常的不酷,我們要讓輪播圖持續(xù)向左循環(huán)怎么辦?
假設(shè)我們要對圖a和圖b兩個圖輪播
我們可以結(jié)尾插入一個與圖a一樣的圖
在兩張圖輪播完后轉(zhuǎn)入第三張圖讓人誤認為是第一張圖片
在第三張圖完成輪播后瞬間跳轉(zhuǎn)至第一張繼續(xù)輪播,此為瞞天過海之計

對于輪播圖我們其實只需要知道原理,且不說框架,jquery完成輪播圖都不要單純手擼的十分之一的精力。
完整代碼
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
*{
margin: 0;
padding: 0;
}
#out{
width:520px;
height:451px ;
margin: 50px auto;
background-color: #00bcd4;
position: relative;
overflow: hidden;
}
#imgList{
list-style: none;
position: absolute;
}
#imgList li{
float:left;
margin: 10px;
}
#navDiv{
position: absolute;
bottom: 15px;
}
#navDiv a{
float: left;
width: 15px;
height: 15px;
background-color: #89ff00;
margin: 0 5px;
opacity: 0.5;
}
#navDiv a:hover{
background-color: red;
/* 內(nèi)聯(lián)樣式的優(yōu)先級很高在觸發(fā)一次后覆蓋失效*/
}
</style>
</head>
<body>
<div id="out">
<ul id="imgList">
<li><img src="pto/many.jpg" ></li>
<li><img src="pto/hello.jpg" ></li>
<li><img src="pto/timg.jpg" ></li>
<li><img src="pto/zhenjing.jpg"></li>
<li><img src="pto/many.jpg" ></li>
</ul>
<div id="navDiv">
<a href="javascript:;" ></a>
<a href="javascript:;" ></a>
<a href="javascript:;" ></a>
<a href="javascript:;" ></a>
</div>
</div>
<script>
window.onload=function () {
// 動態(tài)的ul長度
var imgList = document.getElementById("imgList");
var imgArr = document.getElementsByTagName("img");
imgList.style.width=520*imgArr.length+"px";
//動態(tài)導(dǎo)航居中
var navDiv = document.getElementById("navDiv");
var out = document.getElementById("out");
navDiv.style.left = (out.clientWidth - navDiv.clientWidth)/2+"px";
//定位效果
var allA = document.getElementsByTagName("a");
var index = 0;
allA[index].style.backgroundColor="black";
//點擊導(dǎo)航效果
for(let i=0;i<allA.length;i++){
allA[i].onclick=function () {
move(imgList,-520*i,20);
setA();
// imgList.style.left=-520*i+"px";
// allA[index].style.backgroundColor="";
// index=i;
// allA[index].style.backgroundColor="black";
}
}
// 動畫效果
function move(obj,target,speed,callback) {//元素;目標位置;速度;回調(diào)函數(shù)
clearInterval(obj.timer);
var current = parseInt(window.getComputedStyle(obj,null).left);
//獲得當前位置
//判斷運動方向
if(target<current){
speed = -speed;
}
//定時器標識
obj.timer = window.setInterval(function () {
//m每次開始獲取一下位置
var oldValue = parseInt(window.getComputedStyle(obj,null).left);
//移動并在指定位置停下
var newValue = oldValue + speed;
//調(diào)整一下停止位置,小的誤差會隨時間無限放大
if((speed < 0 && newValue < target)||(speed > 0 && newValue > target)){
newValue = target;
}
imgList.style.left =newValue+"px";
if(newValue == target){
clearInterval(obj.timer);
callback();
}
},30);
}
change();
//自動輪播
//一個定時器用于定時調(diào)用
function change() {
setInterval(function () {
index++;
index=index % imgArr.length ;
move(imgList,-520*index,20,function () {
if(index>=imgArr.length-1 ){
imgList.style.left =0;
}
setA();
});
},3000);
}
function setA() {
for(let i=0;i<allA.length;i++){
allA[i].style.backgroundColor="";
allA[index].style.backgroundColor="black";
}
}
}//onload
</script>
</body>
</html>
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
微信小程序websocket聊天室的實現(xiàn)示例代碼
這篇文章主要介紹了微信小程序websocket聊天室的實現(xiàn)示例代碼,小程序本身對http、websocket等連接均有諸多限制,所以這次項目選擇了node.js自帶的ws模塊。感興趣的可以參考一下2019-02-02
JS實現(xiàn)在線統(tǒng)計一個頁面內(nèi)鼠標點擊次數(shù)的方法
這篇文章主要介紹了JS實現(xiàn)在線統(tǒng)計一個頁面內(nèi)鼠標點擊次數(shù)的方法,實例分析了javascript操作Cookie實現(xiàn)計數(shù)的技巧,需要的朋友可以參考下2015-02-02

