JS原生實現輪播圖的幾種方法
輪播圖
主要思想就是:
在大的容器裡,裝著一個很長的表,表是容器寬度的整數倍。
然後通過更改列表樣式裡的left屬性來實現左右滑動。
本文旨在控制滑動五張圖片,但在html中使用瞭七張圖片,第一張和最後一張是有重復的,至於原因會在下面解釋。
通過給容器設定overflow:hidden屬性來保證隻顯示容器視口大小的一張圖片。
<body> <div id="container"> /*容器*/ <div id="wrap" style="left: -400px;"> /*存放圖片的列表*/ <div class="item item5">l5</div> <div class="item item1">1</div> <div class="item item2">2</div> <div class="item item3">3</div> <div class="item item4">4</div> <div class="item item5">5</div> <div class="item item1">r1</div> </div> </div> <div id="key"> /*設置按鈕*/ <div id="list"> /*點擊小圓圈切換到固定圖片*/ <div class="btn1 btnNum">1</div> <div class="btn2 btnNum">2</div> <div class="btn3 btnNum">3</div> <div class="btn4 btnNum">4</div> <div class="btn5 btnNum">5</div> </div> <div id="btn"> /*向左切換和向右切換的按鈕*/ <button class="left">←</button> <button class="right">→</button> </div> </div> </body>
CSS:
可以給wrap列表設置flex屬性,讓圖片在一行顯示。其他佈局可以按自己需求來做。
註意在定義id=”wrap”d的節點中設置瞭內聯樣式left。因為在切換圖片的時候我用到的是left屬性,而如果不設置left的話,在DOM設置style時是找不到left屬性的。
<style> #container { width: 400px; height: 300px; border: 8px rgb(8, 8, 8) solid; margin: 0 auto; margin-top: 150px; overflow: hidden; position: relative; } #wrap { width: 2800px; height: 300px; display: flex; position: relative; } .item { flex: 1; width: 400px; height: 300px; } .item1 { background-color: rosybrown; } .item2 { background-color: rgb(12, 226, 37); } .item3 { background-color: rgb(212, 221, 29); } .item4 { background-color: rgb(61, 27, 182); } .item5 { background-color: rgb(221, 23, 145); } #key { width: 400px; height: 300px; margin: 0 auto; } #list { width: 400px; height: 40px; display: flex; justify-content: center; } #list div { margin-top: 10px; margin-left: 10px; width: 20px; height: 20px; background-color: rgb(13, 162, 221); text-align: center; border-radius: 45%; opacity: 0.6; } #list div:hover { cursor: pointer; opacity: 1; } #btn { width: 400px; text-align: center; } </style>
這是完整的樣式
每種顏色代表一張圖片,且按序標瞭序號。起始位置是第二張圖片。
至於為什麼第一張和最後一張有額外重復的一張放在兩端,是為瞭在做滑動效果的時候,最後一張(倒數第二張,粉紫色)可以繼續向右順滑的滑到第一張(其實是本圖的第二張,淺棕色的)。第一張(本圖第二張,淺棕色)向左滑動時可以順滑的滑到最後一張(實則倒數第二張)。繼續往下看。
1. 多種輪播方式
輪播必然離開不瞭定位,以及修改wrap列表的left屬性,使其移動。
先初始化幾個數據
var wrap = document.getElementById('wrap'); var nowleft = -400; //用於存放當前列表的left的值 var currIndex = 1; //用於存放當前是第幾個圖片 //定位到幾個按鈕 var btnNum = document.getElementsByClassName('btnNum'); //小圓圈 var right = document.getElementsByClassName('right')[0]; //向右滑的按鈕 var left = document.getElementsByClassName('left')[0]; //向左滑的按鈕
1.1 定時自動輪播效果
隻講向左自動滑動的效果
既然是自動輪播的,那必然少不瞭setInterval()定時器讓其持續輪播。
function next() { setInterval(function() { //設置每兩秒切換一次圖片 wrap.style.transition = 'left 1s' //設定有過渡滑動的效果 nowleft = parseInt(wrap.style.left) - 400; //切換一次後nowleft應該減少(即向左滑)一個圖片的寬度 wrap.style.left = nowleft + 'px'; //然後將nowleft賦值給wrap的left屬性 if(parseInt(wrap.style.left) == -2400) { //判斷到最後一個後,偷偷變回到最開頭的位置 setTimeout(() => { wrap.style.transition = 'none' //因為是偷偷變回去,所以要取消過渡效果 nowleft = -400; wrap.style.left = nowleft + 'px' },1200) //保證定時器的時間大於過度的時間且小於每次輪換的時間 } },2000) }
/由於wrap.style.left 返回的是帶px的字符串,所以用parseInt可以取得前面的數值/
1.2 按向右滑動按鈕
right.addEventListener('click',function() { if(nowleft >= -2000){ //判斷是否到最後一個圖瞭,沒有的話就開始滑動 nowleft -= 400; wrap.style.transition = 'left 1s'; wrap.style.left = nowleft + 'px'; } if(nowleft == -2400) { //如果到最後一個圖瞭,就偷偷換回第一張圖 setTimeout(() => { wrap.style.transition = 'none'; nowleft = -400; wrap.style.left = nowleft + 'px'; },1020) } })
1.3 小圓圈切換圖片
for(let i = 0; i < btnNum.length; i++) { btnNum[0].style.opacity = 1; btnNum[i].addEventListener('click',function() { wrap.style.transition = 'left 1s'; for(let j = 0; j < btnNum.length; j++) { btnNum[j].style.opacity = '0.6'; } btnNum[i].style.opacity = 1; nowleft = nowleft - (i+1 - currIndex)*400; currIndex = i + 1; wrap.style.left = nowleft + 'px'; })
其實本文在控制從最後一個圖偷偷換回第一張圖的操作是有缺陷的,因為要把控序號5的圖滑動到序號為r1的圖是需要1s的,然而wrap.style.left是直接發生變化的,不會隨著過渡期間發生位移而left一直變化。所以把控序號5完整滑動到r1後再偷偷切換到序號1的時間是有些難控制的。
而且比如從序號1連續點擊3下是可以切換到序號4的。然是從序號5連續點擊3下是不可以的,在r1切換到序號1的時候是無法響應點擊效果的,因此此處交互差異會容易感到別扭。
如果想改善這個別扭的bug,可以用下防抖來改善。
到此這篇關於JS原生實現輪播圖的幾種方法的文章就介紹到這瞭,更多相關JS原生輪播圖內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!