摘要:什么是輪播輪播,英文,也就是幻燈片的意思,我們可以手動或者自動切換一張張的照片達到顯示的目的。怎么實現(xiàn)一個輪播一般,我們可以兩種方法來實現(xiàn)輪播,例如,核心思路使用透明度來切換照片,使用距離來平移照片。
什么是輪播
輪播,英文slider,也就是幻燈片的意思,我們可以手動或者自動切換一張張的照片達到顯示的目的。各大電商網(wǎng)站都會使用輪播來展示商品,可以在相對較小的空間里,實現(xiàn)多種展示。
怎么實現(xiàn)一個輪播一般,我們可以兩種方法來實現(xiàn)輪播,例如,核心思路使用透明度來切換照片,使用距離來平移照片。在這里我們使用平移的方式來實現(xiàn)輪播,并通過幾組核心數(shù)據(jù)來實現(xiàn)slide的切換,此外,一般還具有多種方法可以實現(xiàn)無縫切換。
需求分解我們實現(xiàn)的輪播,所需要具有的功能可以分為以下幾部分:
點擊左右箭頭,前后切換slide
無縫切換輪播
點擊輪播中的導(dǎo)航按鈕,切換不同的slide
初始狀態(tài)會每隔3s自動切換slide
鼠標懸浮在slide上時,自動輪播停止,移出后會恢復(fù)自動輪播狀態(tài)
考慮復(fù)用性,抽象為一個組件,其他如點擊切換等功能考慮為插件注入
1. 向前和向后切換和無縫切換 1. 結(jié)構(gòu)和樣式我們設(shè)置兩個容器,通過在父容器使用transform進行左右平移,translateX()是相對于自身的寬度,而在子容器里通過絕對定位來進行平移,其中left屬性相對的是父容器的寬度,這樣父容器平移100%,子容器距離左邊-100%,就可以相互抵消。
HTML結(jié)構(gòu)如下
CSS如下,略有刪減,可以參考源碼
#m-slider { position: relative; width: 100%; height: 100%; transform: translateX(-100%); } .slide { position: absolute; } .slide:nth-child(1) { left: 0%; } .slide:nth-child(2) { left: 100%; } .slide:nth-child(3) { left: 200%; }
此時我們知道可以顯示第二張圖片。
2. 前后邏輯控制數(shù)據(jù)模型:
slideIndex為slide的索引,取值為0,1,2,表示始終只有三張圖片在HTML結(jié)構(gòu)當中。
offset表示當前距離最左邊切換圖片的數(shù)量,每次向后切換時,都會加1,取值范圍為1~圖片的總數(shù)量
相關(guān)說明:
normalIdx()方法是一個將數(shù)字轉(zhuǎn)換為len范圍的方法,接收索引和長度,返回一個在len之內(nèi)的數(shù)值,這里的len固定為3
go()方法,接收1或者-1,分別表示向前和向后移動,以向前移動為例,此時做了兩件事,相關(guān)所以會更新,改變?nèi)萜鞯钠疲饕?b>offset和slideIndex會發(fā)生變化,都需要調(diào)用規(guī)范化方法,使其數(shù)值始終處于3之內(nèi)。
calcDistance()方法為計算移動距離的方法,主要有父容器和slide的距離計算。
var slider = document.getElementById("m-slider") var slides = document.querySelectorAll(".slide") var prev = document.getElementById("prev"); var next = document.getElementById("next"); var slideIndex = 1; // one of 0,1,2 var offset = 1; // 顯示的slide距容器最左邊的偏移量 prev.onclick = function() { go(-1); } next.onclick = function() { go(1); } function normalIdx(index,len) { return (index + len) % len; } function go(foreward) { offset += foreward; // 向右移動了一個,所有偏移量也需要加一 slideIndex += foreward; // 向右移動了一個,所以加一,需要歸三化 slideIndex = normalIdx(slideIndex,3); var prevIndex = normalIdx(slideIndex - 1,3); var nextIndex = normalIdx(slideIndex + 1,3); calcDistance(prevIndex,slideIndex,nextIndex,offset); } function calcDistance(prevIndex,slideIndex,nextIndex,offset) { slider.style.transform = `translateX(${-100*offset}%)` //console.log(slider.style.transform) console.log(offset) // slide offseet slides[prevIndex].style.left = `${100*(offset-1)}%`; slides[slideIndex].style.left = `${100*offset}%`; slides[nextIndex].style.left = `${100*(offset+1)}%`; }2. 無縫輪播
每次切換時,slide的left屬性都會改變,父容器的transform也發(fā)生改變,相互抵消,輕松實現(xiàn)無縫切換,注意: 我們這里只設(shè)置了三張照片,剛好與要求一致,并沒有對相關(guān)數(shù)據(jù)進行計算處理。
/** 不管輪播的照片有多少,只有三欄是常駐的 * ------------------- * | | | | * ------------------------------- * | | | | | | * | | | | | | * | | 1 | 2 | 3 | | * | | | | | | * | | | | | | * ------------------------------- * | | | | * ------------------- */3. 面向?qū)ο蠡?/b>
我們將前面寫的業(yè)務(wù)代碼,用面向?qū)ο蟮乃枷雭碇貥?gòu)一下。
HTML發(fā)生一些改變,我們將Img通過JS動態(tài)注入
JS部分,這里`pageNum表示圖片的總數(shù)量,可以為任意數(shù)字,renderImg()為渲染圖片的方法,主要在切換的時候改變圖片的url,第一次需要進行初始化。
// Component class Slider { constructor(el) { // omit some code this.offset = 1;// 偏移量,即個數(shù) this.slideIndex = 1;// slide index one of 0, 1, 2 this.pageIndex = 1;// page index of total pictures this.pageNum = 6;// total pictures } // 標準化index,使index始終為0,1,2中的一個 normalIdx(index,len) { return (index + len) % len; } // slide move according to the flag go(flag) { // 1. offset and slideIndex change this.offset += flag; this.pageIndex += flag; const slideIndex = this.slideIndex = this.normalIdx( this.slideIndex += flag,3); // 計算移動距離 this.calcDistance(); } // style change calcDistance() { const offset = this.offset; const slideIndex = this.slideIndex; // index const prevIndex = this.normalIdx( slideIndex - 1, 3) const nextIndex = this.normalIdx( slideIndex + 1, 3) this.pageIndex = this.normalIdx(this.pageIndex,this.pageNum) // 2. container and slide move this.container.style.transform = `translateX(${-100 * (offset)}%) `; this.slides[prevIndex].style.left = `${100 * (offset - 1)}%`; this.slides[slideIndex].style.left = `${100 * offset}%`; this.slides[nextIndex].style.left = `${100 * (offset + 1)}%`; //console.log(this.pageIndex,this.slideIndex) this.renderImg(this.pageIndex,this.slideIndex); } renderImg(pageIndex,slideIndex) { for(let i = -1; i <= 1; i++) { const index = (slideIndex+i+3) % 3; // 決定圖片的url和left漂移 let img = this.slides[index].querySelector("img"); let picId = this.normalIdx( pageIndex + i, this.pageNum) + 1; // 頁面初始化使用,運行一次 if(!img) { img = document.createElement("img"); this.slides[index].appendChild(img); } img.src = "http://placehold.it/300x200&text=" + picId + "-Mint"; } } start() { this.bindEvents() this.renderImg(1,1); } } const mySlider = new Slider("m-slider"); mySlider.start()4. 完整版
Source
添加了nav功能,點擊對應(yīng)的小按鈕,即可跳轉(zhuǎn)到指定的slide上
5. 后記后期將考慮將輪播進行組件化,封裝成獨立的組件,添加更多可定制的功能。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/113430.html
摘要:第八集從零開始實現(xiàn)輸入框組件本集定位組件是交互的一大利器他與用戶的交流最為密切所以奠定了他在組件界的重要地位也算是一種如果可以的話本集也會一起說完畢竟是一個類型的一起學完收獲會很大古人云組件不封輸入框,一到面試就發(fā)慌一簡介大家如果對這個 第八集: 從零開始實現(xiàn)(輸入框input,textarea組件) 本集定位: input組件是交互的一大利器, 他與用戶的交流最為密切, 所以奠...
摘要:第八集從零開始實現(xiàn)輸入框組件本集定位組件是交互的一大利器他與用戶的交流最為密切所以奠定了他在組件界的重要地位也算是一種如果可以的話本集也會一起說完畢竟是一個類型的一起學完收獲會很大古人云組件不封輸入框,一到面試就發(fā)慌一簡介大家如果對這個 第八集: 從零開始實現(xiàn)(輸入框input,textarea組件) 本集定位: input組件是交互的一大利器, 他與用戶的交流最為密切, 所以奠...
閱讀 3435·2021-11-19 09:40
閱讀 1324·2021-10-11 11:07
閱讀 4857·2021-09-22 15:07
閱讀 2898·2021-09-02 15:15
閱讀 1972·2019-08-30 15:55
閱讀 544·2019-08-30 15:43
閱讀 886·2019-08-30 11:13
閱讀 1454·2019-08-29 15:36