使用原生js以兩種方式製做一個精美的輪播圖(上)

展現界面 & github源碼javascript

(這裏能夠實現PC端模擬移動端左右滑動圖片切換的效果)

  • github源碼(包含兩種方式實現輪播圖的源碼)

前言

  • 這段時間在學習切頁面的時候,發現頁面上的輪播圖部分讓我很感興趣,由於是剛開始學習javascript,因此想要本身手寫一個輪播圖,因而查閱了好多資料,發現寫輪播圖的方法不少很雜,雖然最終學會了如何使用js寫輪播圖,可是花了我好長時間。
  • 如今我想把本身總結的方法分享出來,其中第二種方法我我的以爲仍是比較有價值的,在網上沒有搜到相似的文章,但願給之後想寫輪播圖的小夥伴一點思路。

需求分析

  • 循環無縫自動輪播四張圖。
  • 能夠手動左右切換圖片(後面我會有兩種手動切換圖片的方式來切換圖片)。
  • 鼠標點擊(觸及)輪播圖下面的小點能夠跳轉到對應的圖片。
看看第一種方法寫的輪播圖的效果:

(這種方法移動到圖片上會中止滾動,顯示按鈕,離開又開始滾動,隱藏按鈕。)

實現原理

  • 首先理解該輪播圖如何滾動,經過控制包含全部圖片的父容器的left值來顯示圖片,在這個容器中只有和視圖容器重疊的部分會顯示出來,其餘的都被隱藏了。
  • 爲了實現「滾動」的效果,咱們須要逐漸改變包含全部圖片的父容器的left值,而不能直接使該值變化圖片寬度的倍數。下面咱們會定義一個動畫效果函數Roll(),這裏能夠先不用管。

實現過程 & 思路

第一種輪播方式比較常見,這裏我就拎重點講,再詳細講一下js部分.CSS和HTML代碼請到github源碼中查看.

HTML部分

  • 這裏用了三個盒子,最外層id爲parent的大盒子內包含了uls和buttons兩個盒子,盒子uls中包含了兩個列表img_ul(圖片列表)和litCir_ul(小圓點列表),盒子buttons裏則包含了「左」,「右」兩個按鈕。

CSS部分

  • 這裏css須要注意的是uls設置了overflow: hidden;因此它的子容器img_ul只會顯示和uls盒子重疊的部分,其餘部分隱藏;
  • 給img_ul設置寬度要長多出一張圖片的寬度,用以放後面克隆的圖片(js部分會詳細講);

JS部分

// 這裏咱們先添加小圓點,讓頁面顯示完整,之所用js添加小圓點,
是由於小圓點的數量應該由圖片張數決定的。
for(let i = 0; i < len;i++){
var a_li = document.createElement('li');//建立li元素節點
a_li.className = 'quiet';//給li添加類名quiet
litCir_ul.appendChild(a_li);
}
複製代碼
  • 將會在下面用到的Html中的對象和一些變量
/*獲取HTML中的對象*/
var parent = document.getElementById("parent");
var img_ul = document.getElementById("img_ul");
var litCir_ul = document.getElementById("litCir_ul");
var buttons = document.getElementById("buttons");
var cLis =litCir_ul.children;         //children 屬性返回元素的子元素的集合
//定義一些變量
var len = img_ul.children.length;     //圖片張數
var width = parent.offsetWidth;       //每張圖片的寬度
var rate = 15;                        //一張圖片的切換速度, 單位爲px
var times = 1;                        //切換速度的倍率
var gap = 2000;                       //自動切換間隙, 單位爲毫秒
var timer = null;                     //初始化一個定時器
var picN = 0;                         //當前顯示的圖片下標
var cirN = 0;                         //當前顯示圖片的小圓點下標
var temp;
複製代碼
  • 首先理解無縫滾動是怎麼作到的,這裏定義一個動畫效果函數Roll();經過傳進來的distance來控制img_ul的位置來顯示,設置img_ul的left值,以達到圖片滾動的.
function Roll(distance){                                         //參數distance:滾動的目標點(必爲圖片寬度的倍數)
    clearInterval(img_ul.timer);                                     //每次運行該函數必須清除以前的定時器!
    var speed = img_ul.offsetLeft < distance ?  rate : (0-rate);     //判斷圖片移動的方向  此處用了三元運算符  ? 前面的不等式成立時爲rate,不成立時爲0-rete
        // console.log(speed)
    img_ul.timer = setInterval(function(){                           //設置定時器,每隔10毫秒,調用一次該匿名函數
        img_ul.style.left = img_ul.offsetLeft + speed + "px";        //每一次調用滾動到的地方 (速度爲 speed px/10 ms)       offsetLeft爲元素邊框外側到父元素邊框內側的距離    
        var leave = distance - img_ul.offsetLeft;                    //距目標點剩餘的px值      
        /*接近目標點時的處理,滾動接近目標時直接到達, 避免rate值設置不當時不能完整顯示圖片*/
        if (Math.abs(leave) <= Math.abs(speed)) {                    
            clearInterval(img_ul.timer);
            img_ul.style.left = distance + "px";
        }
    },10);
    }
複製代碼
  • 當圖片從最後一張切換到第一張時,這時就不能經過逐漸改變img_ul的left值來實現滾動的效果,因而克隆第一張圖片至列表尾部,當滾動完最後一張圖片時,繼續滾動到克隆的第一張,而後將img_ul的left值重置爲0。
img_ul.appendChild(img_ul.children[0].cloneNode(true));//克隆第一張圖片至列表尾部
複製代碼
  • 定義自動滾動函數autoRun()
function autoRun(){
        picN++
        cirN++
        //若是輪播完克隆項應該輪播回第二張照片上,由於克隆項和第一張圖片同樣
        if(picN > len) {
            img_ul.style.left = 0;//改變left至真正的第一項處,這個過程是時間太快過短因此能夠忽略不計而後馬上
            picN = 1;   //從第二張開始顯示
        }
        // 自動輪播,當圖片爲第一張時應該自動到第二張上去,因此要傳入第二張的picN值,依次類推
        Roll(-picN*width)
        //判斷是否到了最後一個圓點,當圓點到了最後一個時,應該變回第一個點進行輪播
        if (cirN > len - 1) {
            cirN = 0;
        }
        for(var i = 0; i < len;i++) {
            cLis[i].className = 'quiet';//讓全部圓點背景色變爲默認色
        }
        cLis[cirN].className = 'active';
    }
複製代碼
  • 注意:以上輪播圖片時是當圖片索引值picN已經有了,要+1,等待必定時間執行移動到下一張圖片的事件
    開始自動滾動:
    timer = setInterval(autoRun, gap); //定時器
    複製代碼
  • 給小圓點設置觸及事件
    for(let j = 0;j < len ;j++){
        cLis[j].index = j;//給每一個圓點一個索引值
        cLis[j].onmouseover = function() {
            for(var k = 0; k < len;k++) {
                cLis[k].className = 'quiet';//讓全部圓點背景色變爲默認色
            }
            this.className = 'active';
            temp = cirN;
            picN = cirN = this.index;
            times = Math.abs(this.index - temp);//距離上個小圓點的距離
            rate = rate*times;//根據距離改變切換速率
            Roll(-this.index * width);
            rate = 15;
        }
    }
    複製代碼
  • 接下來是觸及輪播圖區域,圖片中止輪播,顯示左右按鈕,離開該區域時,又從新開始定時器的自動輪播,左右按鈕隱藏.
    //觸及輪播圖區域,清除定時器
    parent.onmouseover = function(){
        clearInterval(timer);
        buttons.style.display = 'block';
    }//離開該區域時,從新開始定時器的自動輪播
    parent.onmouseout = function(){
        buttons.style.display = 'none';
        timer = setInterval(autoRun, gap);
    }
    複製代碼
  • 下面是設置左右按鈕點擊切換圖片的事件.
    //給左邊按鈕添加點擊事件
    buttons.children[0].onclick = function() {
        picN--;
        cirN--;
        if(picN < 0){
            img_ul.style.left = -len*width + 'px';
            picN = len - 1;
        }
        Roll(-picN*width);
        if(cirN < 0){
            cirN = len - 1;
        }
        for(var i = 0; i < len; i++) {
            cLis[i].className = 'quiet';
        }
        cLis[cirN].className = 'active';
    }
    //給右邊按鈕添加點擊事件
    buttons.children[1].onclick = autoRun;
    //自動播放就是間隔必定時間不斷調用函數「下一張」的過程,因此這裏的
    按鈕right下一張的實現就是上面的autoRun函數。
    複製代碼

總結

原本想寫兩種方式實現輪播圖的,因爲第一次在掘金社區裏寫文章,沒有控制好字數,感受寫的太長太多了,因此這裏先寫第一種原生js方式的實現輪播圖。若是想了解第二種原生js是如何實現輪播圖的話,我會繼續更新的哦!請持續關注,這也是筆者的第一篇文章,若是各位看官喜歡請點贊收藏,這對筆者是莫大的鼓勵😊。css

相關文章
相關標籤/搜索