JavaScript Dom實現輪播圖原理和例項
想要製作一個輪播圖我們要先弄清楚他的原理,如何能讓圖片自右向左滑動?
讓我們想一想生活中有沒有類似的東西,比如電影膠片。
我們可以建立一個塊作為投影區,建立一個列表作為底片並使其向左移動,達到輪播圖效果。
建立一個塊和列表
建立一個塊作為總的容器和顯示區域。
<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>
現在圖片豎著堆在一列,塊也不知道在哪裡,那新增一點樣式
開啟定位並令其居中,並且讓塊大一點並新增背景好確定位置(本實驗圖片統一寬高比500*431,所以div寬高比520*451)
去掉列表預設樣式讓列表橫著顯示
*{ margin: 0; padding: 0; } #out{ width:520px; height:451px ; background-color: #00bcd4; position: relative; margin: 50px auto; /*overflow: hidden;*/ /*剪掉我們不需要的部分,為了方便除錯注掉了*/ } #imgList{ list-style: none; position: absolute; /* left: -520px; */ } #imgList li{ float:left; margin: 10px; }
在嘗試浮動後圖片依舊是一列,是因為lu的寬度太小放不下,所以我們要擴大,但是我們不能直接決定他的寬度因為隨著圖片的增加,寬度應不斷變大,於是我們用JavaScript來解決寬度
每增加一張圖片擴大520px寬度
window.onload=function () { // 動態的ul長度 var imgList = document.getElementById("imgList"); var imgArr = document.getElementsByTagName("img"); imgList.style.width=520*imgArr.length+"px"; }//onload
現在,裝載圖片的膠片ul每向左偏移-520px就會更換一個圖片
導航欄
輪播圖會定時更換,但是有可能你的客戶剛剛被吸引就已經更換圖片了,如果你想讓你的客戶乾巴巴的瞪著圖片回來,你很可能失去她。
所以一個完整的輪播圖還需要一個能手動切換前後的按鈕或一個導航條。
我們這裡用幾個超連結完成任務
<div id="navDiv"> <a href="javascript:;"></a> <a href="javascript:;"></a> <a href="javascript:;"></a> <a href="javascript:;"></a> </div>
ul在開啟絕對定位後脫離文件流,現在我們的導航因為沒有內容縮成一團擠在左上角
我們要讓每一個超聯接彼此分開,手動撐開空間,調整到靠下的位置,下方正中或靠右是比較好的選擇.
調整透明度降低導航對於人的吸引力,畢竟圖片才是主題。
而位置的調整為了便於擴充我們還是要用js來解決。
} #navDiv{ position: absolute; bottom: 15px; } #navDiv a{ float: left; width: 15px; height: 15px; background-color: #89ff00; margin: 0 5px; opacity: 0.5; }
//動態導航居中 var navDiv = document.getElementById("navDiv"); var out = document.getElementById("out"); //將縱向剩餘距離分到導航左右達到居中效果 //不除以二就會變成右對齊 //不要忘了單位,嗯。。可能只有我會忘吧 navDiv.style.left = (out.clientWidth - navDiv.clientWidth)/2+"px";
導航功能完善
一僅僅個15px大的方塊要給使用者怎樣的反饋?
當前圖片所處位置,當滑鼠移動到導航是時要反饋資訊告訴使用者我是可以點選的,點選導航能切換圖片。
#navDiv a:hover{ background-color: red; /* 滑鼠移入效果*/ /* 內聯樣式的優先順序很高注意不要被覆蓋失效*/ }
//定位效果 var allA = document.getElementsByTagName("a"); var index = 0; allA[index].style.backgroundColor="black"; //點選導航效果 //使用塊級作用域let,不然i會是同一個數 for(let i=0;i<allA.length;i++){ allA[i].onclick=function () { imgList.style.left=-520*i+"px"; //清除內聯樣式,使得css檔案能生效 allA[index].style.backgroundColor=""; index=i; allA[index].style.backgroundColor="black"; } }
動畫效果
為什麼要做動畫? (因為很酷(≧ω≦*)♪ )
因為沒有輪播效果不叫輪播圖,明明更改地址就能完成,忙活半天不就是為了這個,用最大的標題告訴你動畫才是輪播圖的精髓所在
主要思路是利用定時器讓本來一部完成的效果多次完成,到達指定位置關閉定時器。
要注意的問題
每次移動距離與圖片大小可能除餘,導致停止位置不準確(大於或小於)或無法停止(不能剛好到達停止位置),小的誤差會逐漸積累。
在定時器開啟前關閉上一個計時器,否則在一個動畫未完成前點選另一個會發生鬼畜現象
//點選導航效果 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) {//元素;目標位置;速度 //每次觸發事件關閉上一個定時器 //這裡是重點,你可以去掉這一句後隨意點一下關差效果 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; //調整一下停止位置,小的誤差會隨時間無限放大 if((speed < 0 && newValue < target)||(speed > 0 && newValue > target)){ newValue = target; } imgList.style.left =newValue+"px"; if(newValue == target){ clearInterval(obj.timer); } },30); }
change(); //自動輪播 //一個定時器用於定時呼叫 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); }
這樣已經能做到輪播的基本功能,但在最後一張圖片切換第一張圖片時會向左拉過全部圖片,這非常的不酷,我們要讓輪播圖持續向左迴圈怎麼辦?
假設我們要對圖a和圖b兩個圖輪播
我們可以結尾插入一個與圖a一樣的圖
在兩張圖輪播完後轉入第三張圖讓人誤認為是第一張圖片
在第三張圖完成輪播後瞬間跳轉至第一張繼續輪播,此為瞞天過海之計
對於輪播圖我們其實只需要知道原理,且不說框架,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; /* 內聯樣式的優先順序很高在觸發一次後覆蓋失效*/ } </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 () { // 動態的ul長度 var imgList = document.getElementById("imgList"); var imgArr = document.getElementsByTagName("img"); imgList.style.width=520*imgArr.length+"px"; //動態導航居中 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"; //點選導航效果 for(let i=0;i<allA.length;i++){ allA[i].onclick=function () { move(imgList,20); setA(); // imgList.style.left=-520*i+"px"; // allA[index].style.backgroundColor=""; // index=i; // allA[index].style.backgroundColor="black"; } } // 動畫效果 function move(obj,speed,callback) {//元素;目標位置;速度;回撥函式 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; //調整一下停止位置,小的誤差會隨時間無限放大 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(); //自動輪播 //一個定時器用於定時呼叫 function change() { setInterval(function () { index++; index=index % imgArr.length ; move(imgList,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>
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。