JavaScript Dom實(shí)現(xiàn)輪播圖原理和實(shí)例
想要制作一個(gè)輪播圖我們要先弄清楚他的原理,如何能讓圖片自右向左滑動(dòng)?讓我們想一想生活中有沒(méi)有類似的東西,比如電影膠片。我們可以創(chuàng)建一個(gè)塊作為投影區(qū),創(chuàng)建一個(gè)列表作為底片并使其向左移動(dòng),達(dá)到輪播圖效果。
創(chuàng)建一個(gè)塊作為總的容器和顯示區(qū)域。
<div id='out'> <ul id='imgList'> <li><img src='http://www.aoyou183.cn/bcjs/pto/many.jpg' ></li> <li><img src='http://www.aoyou183.cn/bcjs/pto/hello.jpg' ></li> <li><img src='http://www.aoyou183.cn/bcjs/pto/timg.jpg' ></li> <li><img src='http://www.aoyou183.cn/bcjs/pto/zhenjing.jpg'></li> </ul></div>
現(xiàn)在圖片豎著堆在一列,塊也不知道在哪里,那添加一點(diǎn)樣式
開(kāi)啟定位并令其居中,并且讓塊大一點(diǎn)并添加背景好確定位置(本實(shí)驗(yàn)圖片統(tǒng)一寬高比500*431,所以div寬高比520*451)
去掉列表默認(rèn)樣式讓列表橫著顯示
*{ 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;}
在嘗試浮動(dòng)后圖片依舊是一列,是因?yàn)閘u的寬度太小放不下,所以我們要擴(kuò)大,但是我們不能直接決定他的寬度因?yàn)殡S著圖片的增加,寬度應(yīng)不斷變大,于是我們用JavaScript來(lái)解決寬度每增加一張圖片擴(kuò)大520px寬度
window.onload=function () { // 動(dòng)態(tài)的ul長(zhǎng)度 var imgList = document.getElementById('imgList'); var imgArr = document.getElementsByTagName('img'); imgList.style.width=520*imgArr.length+'px'; }//onload
現(xiàn)在,裝載圖片的膠片ul每向左偏移-520px就會(huì)更換一個(gè)圖片
導(dǎo)航欄輪播圖會(huì)定時(shí)更換,但是有可能你的客戶剛剛被吸引就已經(jīng)更換圖片了,如果你想讓你的客戶干巴巴的瞪著圖片回來(lái),你很可能失去她。所以一個(gè)完整的輪播圖還需要一個(gè)能手動(dòng)切換前后的按鈕或一個(gè)導(dǎo)航條。我們這里用幾個(gè)超鏈接完成任務(wù)
<div id='navDiv'> <a href='javascript:;'></a> <a href='javascript:;'></a> <a href='javascript:;'></a> <a href='javascript:;'></a></div>
ul在開(kāi)啟絕對(duì)定位后脫離文檔流,現(xiàn)在我們的導(dǎo)航因?yàn)闆](méi)有內(nèi)容縮成一團(tuán)擠在左上角我們要讓每一個(gè)超聯(lián)接彼此分開(kāi),手動(dòng)撐開(kāi)空間,調(diào)整到靠下的位置,下方正中或靠右是比較好的選擇.調(diào)整透明度降低導(dǎo)航對(duì)于人的吸引力,畢竟圖片才是主題。而位置的調(diào)整為了便于擴(kuò)充我們還是要用js來(lái)解決。
} #navDiv{ position: absolute; bottom: 15px; } #navDiv a{ float: left; width: 15px; height: 15px; background-color: #89ff00; margin: 0 5px; opacity: 0.5; }
//動(dòng)態(tài)導(dǎo)航居中 var navDiv = document.getElementById('navDiv'); var out = document.getElementById('out'); //將縱向剩余距離分到導(dǎo)航左右達(dá)到居中效果 //不除以二就會(huì)變成右對(duì)齊 //不要忘了單位,嗯。。可能只有我會(huì)忘吧 navDiv.style.left = (out.clientWidth - navDiv.clientWidth)/2+'px';導(dǎo)航功能完善
一僅僅個(gè)15px大的方塊要給用戶怎樣的反饋?當(dāng)前圖片所處位置,當(dāng)鼠標(biāo)移動(dòng)到導(dǎo)航是時(shí)要反饋信息告訴用戶我是可以點(diǎn)擊的,點(diǎn)擊導(dǎo)航能切換圖片。
#navDiv a:hover{ background-color: red; /* 鼠標(biāo)移入效果*/ /* 內(nèi)聯(lián)樣式的優(yōu)先級(jí)很高注意不要被覆蓋失效*/ }
//定位效果var allA = document.getElementsByTagName('a');var index = 0; allA[index].style.backgroundColor='black'; //點(diǎn)擊導(dǎo)航效果 //使用塊級(jí)作用域let,不然i會(huì)是同一個(gè)數(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'; } }動(dòng)畫效果
為什么要做動(dòng)畫? (因?yàn)楹芸??ω?*)♪ )
因?yàn)闆](méi)有輪播效果不叫輪播圖,明明更改地址就能完成,忙活半天不就是為了這個(gè),用最大的標(biāo)題告訴你動(dòng)畫才是輪播圖的精髓所在
主要思路是利用定時(shí)器讓本來(lái)一部完成的效果多次完成,到達(dá)指定位置關(guān)閉定時(shí)器。
要注意的問(wèn)題
每次移動(dòng)距離與圖片大小可能除余,導(dǎo)致停止位置不準(zhǔn)確(大于或小于)或無(wú)法停止(不能剛好到達(dá)停止位置),小的誤差會(huì)逐漸積累。在定時(shí)器打開(kāi)前關(guān)閉上一個(gè)計(jì)時(shí)器,否則在一個(gè)動(dòng)畫未完成前點(diǎn)擊另一個(gè)會(huì)發(fā)生鬼畜現(xiàn)象
//點(diǎ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'; //換掉這個(gè)很low的過(guò)場(chǎng) allA[index].style.backgroundColor=''; index=i; allA[index].style.backgroundColor='black'; } } function move(obj,target,speed) {//元素;目標(biāo)位置;速度 //每次觸發(fā)事件關(guān)閉上一個(gè)定時(shí)器 //這里是重點(diǎn),你可以去掉這一句后隨意點(diǎn)一下關(guān)差效果 clearInterval(obj.timer); var current = parseInt(window.getComputedStyle(obj,null).left); //獲得當(dāng)前位置 //判斷運(yùn)動(dòng)方向 if(target<current){ speed = -speed; } //定時(shí)器標(biāo)識(shí) obj.timer = window.setInterval(function () { //m每次開(kāi)始獲取一下當(dāng)前位置 var oldValue = parseInt(window.getComputedStyle(obj,null).left); //移動(dòng)并在指定位置停下 var newValue = oldValue + speed; //調(diào)整一下停止位置,小的誤差會(huì)隨時(shí)間無(wú)限放大 if((speed < 0 && newValue < target)||(speed > 0 && newValue > target)){ newValue = target; } imgList.style.left =newValue+'px'; if(newValue == target){ clearInterval(obj.timer); } },30); }
change(); //自動(dòng)輪播 //一個(gè)定時(shí)器用于定時(shí)調(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)能做到輪播的基本功能,但在最后一張圖片切換第一張圖片時(shí)會(huì)向左拉過(guò)全部圖片,這非常的不酷,我們要讓輪播圖持續(xù)向左循環(huán)怎么辦?
假設(shè)我們要對(duì)圖a和圖b兩個(gè)圖輪播
我們可以結(jié)尾插入一個(gè)與圖a一樣的圖在兩張圖輪播完后轉(zhuǎn)入第三張圖讓人誤認(rèn)為是第一張圖片在第三張圖完成輪播后瞬間跳轉(zhuǎn)至第一張繼續(xù)輪播,此為瞞天過(guò)海之計(jì)
對(duì)于輪播圖我們其實(shí)只需要知道原理,且不說(shuō)框架,jquery完成輪播圖都不要單純手?jǐn)]的十分之一的精力。
完整代碼<!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)先級(jí)很高在觸發(fā)一次后覆蓋失效*/ } </style></head><body><div id='out'> <ul id='imgList'> <li><img src='http://www.aoyou183.cn/bcjs/pto/many.jpg' ></li> <li><img src='http://www.aoyou183.cn/bcjs/pto/hello.jpg' ></li> <li><img src='http://www.aoyou183.cn/bcjs/pto/timg.jpg' ></li> <li><img src='http://www.aoyou183.cn/bcjs/pto/zhenjing.jpg'></li> <li><img src='http://www.aoyou183.cn/bcjs/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 () { // 動(dòng)態(tài)的ul長(zhǎng)度 var imgList = document.getElementById('imgList'); var imgArr = document.getElementsByTagName('img'); imgList.style.width=520*imgArr.length+'px'; //動(dòng)態(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'; //點(diǎn)擊導(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'; } } // 動(dòng)畫效果 function move(obj,target,speed,callback) {//元素;目標(biāo)位置;速度;回調(diào)函數(shù) clearInterval(obj.timer); var current = parseInt(window.getComputedStyle(obj,null).left); //獲得當(dāng)前位置 //判斷運(yùn)動(dòng)方向 if(target<current){ speed = -speed; } //定時(shí)器標(biāo)識(shí) obj.timer = window.setInterval(function () { //m每次開(kāi)始獲取一下位置 var oldValue = parseInt(window.getComputedStyle(obj,null).left); //移動(dòng)并在指定位置停下 var newValue = oldValue + speed; //調(diào)整一下停止位置,小的誤差會(huì)隨時(shí)間無(wú)限放大 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(); //自動(dòng)輪播 //一個(gè)定時(shí)器用于定時(shí)調(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>
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持好吧啦網(wǎng)。
相關(guān)文章:
1. phpstudy apache開(kāi)啟ssi使用詳解2. ASP.NET Core按用戶等級(jí)授權(quán)的方法3. ASP常用日期格式化函數(shù) FormatDate()4. HTML中的XML數(shù)據(jù)島記錄編輯與添加5. 利用FastReport傳遞圖片參數(shù)在報(bào)表上展示簽名信息的實(shí)現(xiàn)方法6. 詳解瀏覽器的緩存機(jī)制7. .NET 中配置從xml轉(zhuǎn)向json方法示例詳解8. ASP新手必備的基礎(chǔ)知識(shí)9. ASP中if語(yǔ)句、select 、while循環(huán)的使用方法10. 推薦一個(gè)好看Table表格的css樣式代碼詳解
