js原生的輪播,原理以及實踐

 

輪播,不管是文字輪播仍是圖片輪播,他們的原理是同樣的,都是經過定時器執行循環展現和影藏。javascript

1、手動輪播css

(1)原理html

一系列的大小相等的圖片平鋪,利用CSS佈局只顯示一張圖片,其他隱藏。經過計算偏移量利用定時器實現自動播放,或經過手動點擊事件切換圖片。java

(2)實現web

如何利用css實現佈局顯示一張圖片?主要的屬性是over-follow:hidden。首先給容器一個固定的長和寬,而後設置over-flow:hidden。數組

一、html結構閉包

 首先父容器container存放全部內容,子容器list存在圖片。子容器buttons存放按鈕小圓點。dom

<div id="container">
            <div id="list" style="left: -600px;">
                <img src="img/5.png" alt="1" />
                <img src="img/1.png" alt="1" />
                <img src="img/2.png" alt="2" />
                <img src="img/3.png" alt="3" />
                <img src="img/4.png" alt="4" />
                <img src="img/5.png" alt="5" />
                <img src="img/1.png" alt="5" />
            </div>
            <div id="buttons">
                <span index="1" class="on"></span>
                <span index="2"></span>
                <span index="3"></span>
                <span index="4"></span>
                <span index="5"></span>
            </div>
            <a href="javascript:;" id="prev" class="arrow">&lt;</a>
            <a href="javascript:;" id="next" class="arrow">&gt;</a>
        </div>

優化,無縫滾動。ide

當你從最後一張圖切換回第一張圖時,有很大空白,利用兩張輔助圖來填補這個空白。函數

這裏補充下無縫滾動,直接看代碼,複製最後一張圖片放置第一張圖片前,同時複製第一張圖片放置最後一張圖片的後面。而且,將第一張圖片輔助圖(其實是實際顯示的第5張圖片隱藏起來,故設置style="left: -600px;")

 

 

二、css樣式

一、對盒子模型,文檔流的理解,絕對定位問題。

二、注意list的overflow:hidden;只顯示窗口的一張圖片,把左右兩邊的都隱藏起來。

三、確保buttons中每一個span所在層置頂,將其設置爲最頂端。

            * {
                margin: 0;
                padding: 0;
                text-decoration: none;
            }
            
            body {
                padding: 20px;
            }
            
            #container {
                position: relative;
                width: 600px;
                height: 400px;
                border: 3px solid #333;
                overflow: hidden;
            }
            
            #list {
                position: absolute;
                z-index: 1;
                width: 4200px;
                height: 400px;
            }
            
            #list img {
                float: left;
                width: 600px;
                height: 400px;
            }
            
            #buttons {
                position: absolute;
                left: 250px;
                bottom: 20px;
                z-index: 2;
                height: 10px;
                width: 100px;
            }
            
            #buttons span {
                float: left;
                margin-right: 5px;
                width: 10px;
                height: 10px;
                border: 1px solid #fff;
                border-radius: 50%;
                background: #333;
                cursor: pointer;
            }
            
            #buttons .on {
                background: orangered;
            }
            
            .arrow {
                position: absolute;
                top: 180px;
                z-index: 2;
                display: none;
                width: 40px;
                height: 40px;
                font-size: 36px;
                font-weight: bold;
                line-height: 35px;
                text-align: center;
                color: #fff;
                background-color: RGBA(0, 0, 0, .3);
                cursor: pointer;
            }
            
            .arrow:hover {
                background-color: RGBA(0, 0, 0, .7);
            }
            
            #container:hover .arrow {
                display: block;
            }
            
            #prev {
                left: 20px;
            }
            
            #next {
                right: 20px;
            }

 

三、JS實現

首先咱們先實現出手動點擊左右兩個箭頭切換圖片的效果:

window.onload = function() {
        var list = document.getElementById('list');
        var prev = document.getElementById('prev');
        var next = document.getElementById('next');

        function animate(offset) {
            //獲取的是style.left,是相對左邊獲取距離,因此第一張圖後style.left都爲負值,
            //且style.left獲取的是字符串,須要用parseInt()取整轉化爲數字。
            var newLeft = parseInt(list.style.left) + offset;
            list.style.left = newLeft + 'px';
            if(newLeft<-3000){
                list.style.left = -600 + 'px';
            }
            if(newLeft>-600){
                list.style.left = -3000 + 'px';
            }
        }

        prev.onclick = function() {
            animate(600);
        }
        next.onclick = function() {
            animate(-600);
        }
    }

效果以下圖所示

 

運行後咱們會發現,一直點擊右箭頭 ,會出現空白,並且,不能回到第一張圖片。要點擊左箭頭才能回到第一張圖片。

 緣由是咱們利用偏移量left來獲取圖片,當看到left值小於3600時,由於沒有第8張圖片就出現空白,因此這裏咱們須要對偏移量作一個判斷。

if(newLeft<-3000){
                list.style.left = -600 + 'px';
            }
            if(newLeft>-600){
                list.style.left = -3000 + 'px';
            }

加了這個判斷就是說,在實時的left值在小於-3000的時候,經過操做dom元素直接把left值給到-600,回到初始化的狀態。

 

可是輪播有自動輪播和手動輪播。上面基本實現的是手動點擊進行輪播(手動輪播)。

 

2、自動輪播

要實現自動,必須有定時器進行計時。

對於定時器,有必要說明一下setInterval()跟setTimeout的區別了。

簡單來講,setInterval()執行屢次,setTimeout()只執行一次。

因此自動輪播須要咱們每隔一段時間執行一次,選擇setInterval()函數。

/*自動循環播放*/
        var timer;
        function play(){
            timer = setInterval(function(){
                prev.onclick();
            },1500)
        }
        play();

 

完美實現了自動輪播

可是,當咱們想仔細看某一張圖片時候,要把圖片停住,咱們清楚定時器就能夠

 

3、手動能夠干預輪播

我想仔細看某一張照片時候,要圖片停住,須要用到window.clearInterval 這個方法。

這裏,咱們須要對其DOM操做,須要獲取整個輪播圖區域,鼠標進入到容器區域就清空計時器。

/*鼠標放上(離開)對應輪播暫停(播放)*/
        var container = document.getElementById('container');
        function stop() {
            clearInterval(timer);
        }
        container.onmouseover = stop;
        container.onmouseout = play;

效果,以下圖所示:

一個鼠標放上輪播暫停的實現就完美實現了。

 

如今回顧一下,的確很簡單,不是很難,並非必需要用插件實現,原生的js也能夠實現,你能夠優化一下封裝成本身的輪播插件。

(1)容器的css佈局。

(2)每一次輪播經過偏移量left實現,手動輪播的按鈕綁定每一次偏移量增長仍是減小一張照片寬度的偏移量。

(3)自動輪播,經過setInterval()方法實現定時器,執行下一張的點擊函數

(4)鼠標控制輪播的暫停和繼續。經過onmouseover爲暫停,onmouseout爲繼續。

完整代碼:

<!DOCTYPE html>
<html>

    <head>
        <meta charset="utf-8" />
        <title></title>
        <style type="text/css">
            * {
                margin: 0;
                padding: 0;
                text-decoration: none;
            }
            
            body {
                padding: 20px;
            }
            
            #container {
                position: relative;
                width: 600px;
                height: 400px;
                border: 3px solid #333;
                overflow: hidden;
            }
            
            #list {
                position: absolute;
                z-index: 1;
                width: 4200px;
                height: 400px;
            }
            
            #list img {
                float: left;
                width: 600px;
                height: 400px;
            }
            
            #buttons {
                position: absolute;
                left: 250px;
                bottom: 20px;
                z-index: 2;
                height: 10px;
                width: 100px;
            }
            
            #buttons span {
                float: left;
                margin-right: 5px;
                width: 10px;
                height: 10px;
                border: 1px solid #fff;
                border-radius: 50%;
                background: #333;
                cursor: pointer;
            }
            
            #buttons .on {
                background: orangered;
            }
            
            .arrow {
                position: absolute;
                top: 180px;
                z-index: 2;
                display: none;
                width: 40px;
                height: 40px;
                font-size: 36px;
                font-weight: bold;
                line-height: 35px;
                text-align: center;
                color: #fff;
                background-color: RGBA(0, 0, 0, .3);
                cursor: pointer;
            }
            
            .arrow:hover {
                background-color: RGBA(0, 0, 0, .7);
            }
            
            #container:hover .arrow {
                display: block;
            }
            
            #prev {
                left: 20px;
            }
            
            #next {
                right: 20px;
            }
        </style>
    </head>

    <body>
        <div id="container">
            <div id="list" style="left: -600px;">
                <img src="img/5.png" alt="1" />
                <img src="img/1.png" alt="1" />
                <img src="img/2.png" alt="2" />
                <img src="img/3.png" alt="3" />
                <img src="img/4.png" alt="4" />
                <img src="img/5.png" alt="5" />
                <img src="img/1.png" alt="5" />
            </div>
            <div id="buttons">
                <span index="1" class="on"></span>
                <span index="2"></span>
                <span index="3"></span>
                <span index="4"></span>
                <span index="5"></span>
            </div>
            <a href="javascript:;" id="prev" class="arrow">&lt;</a>
            <a href="javascript:;" id="next" class="arrow">&gt;</a>
        </div>

    </body>

</html>

<script>
    window.onload = function() {
        var list = document.getElementById('list');
        var prev = document.getElementById('prev');
        var next = document.getElementById('next');

        function animate(offset) {
            /*獲取的是style.left,是相對左邊獲取距離,因此第一張圖後style.left都爲負值,
            且style.left獲取的是字符串,須要用parseInt()取整轉化爲數字。*/
            var newLeft = parseInt(list.style.left) + offset;
            list.style.left = newLeft + 'px';
            if(newLeft < -3000) {
                list.style.left = -600 + 'px';
            }
            if(newLeft > -600) {
                list.style.left = -3000 + 'px';
            }
        }
        /*上一步*/
        prev.onclick = function() {
                animate(600);
            }
            /*下一步*/
        next.onclick = function() {
                animate(-600);
            }
            /*自動循環播放*/
        var timer;

        function play() {
            timer = setInterval(function() {
                prev.onclick();
            }, 1500)
        }
        play();
        /*鼠標放上(離開)對應輪播暫停(播放)*/
        var container = document.getElementById('container');
        function stop() {
            clearInterval(timer);
        }
        container.onmouseover = stop;
        container.onmouseout = play;
    }
</script>
View Code

 

4、小點也隨着圖片進行輪播

首先要能拿到有多少個小點的數組,而後每一次的下一步的時候判斷一下當前的小圓點的標誌位。

(1)當標誌位大於數組的長度時候,須要把標誌位賦值爲初始值

/*上一步*/
        prev.onclick = function() {
                index = index -1;
                if(index < 1) {
                    index = 5;
                }
                buttonShow();
                animate(600);
            }
            /*下一步*/
        next.onclick = function() {
                index = index + 1;
                if(index > 5) {
                    index = 1;
                }
                buttonShow();
                animate(-600);
            }

(2)每執行一次下一步,標誌位temp+1,同時將圓點的上一個樣式清除,下一個顯示選中樣式。

function buttonShow() {
            /*console.log(buttons.length);*/
            /*清除以前的樣式*/
            for(var i = 0; i < buttons.length; i++) {
                if(buttons[i].className === 'on') {
                    buttons[i].className = '';
                }
            }
            /*數組從0開始,temp從-1開始*/
            buttons[index - 1].className = 'on';
        }

最後效果以下圖所示:

 

5、小點能夠點擊到對應的圖片上

忽然發現圖片下邊還有一堆小點,須要給增長點擊事件,點擊哪個點,就到哪一張圖片上。

/*小圓點的點擊事件*/
        for(var i =0;i<buttons.length;i++){
            buttons[i].onclick = function (){
                console.log(i);
                /*偏移量的獲取:獲取鼠標的小圓點的位置,用this把index綁定到對象buttons[i]上*/
                /*因爲index是自定義屬性,須要用到getAttribute()這個dom的2級方法,去獲取自定義的index屬性*/
                var clickIndex = parseInt(this.getAttribute('index'));
                var offset = 600*(index-clickIndex);
                animate(offset);
                index = clickIndex;
                buttonShow();
            }
        }

要大功告成了,可是發現控制檯會發現打印出來的永遠的是i=5。

                                       「對javascript來講,由for語句建立的變量i即便在for循環執行結束後,也依舊會存在於循環外部的執行環境中。」

就是說,js沒有塊級做用域這東西,(可能我C寫多了,混淆了)。在第一次循環(從 i=0 到 4 這一過程)結束後,最後的 i 獲取到的爲 buttons.length 的值被

保存在for循環以外,最後鼠標點擊任何一個小圓點時,天然訪問的一直是 i=5 了。

使用當即函數

/*小圓點的點擊事件*/
        for(var i = 0; i < buttons.length; i++) {
            /*使用當即函數*/
            (function(i) {
                buttons[i].onclick = function() {
                    console.log(i);
                    /*偏移量的獲取:獲取鼠標的小圓點的位置,用this把index綁定到對象buttons[i]上*/
                    /*因爲index是自定義屬性,須要用到getAttribute()這個dom的2級方法,去獲取自定義的index屬性*/
                    var clickIndex = parseInt(this.getAttribute('index'));
                    var offset = 600 * (index - clickIndex);
                    animate(offset);
                    index = clickIndex;
                    buttonShow();
                }
            })(i)
        }

這裏涉及到js的閉包問題。

 

完美原生js實現輪播,原理以及實踐。總結一下:

原理:(1)使用的是css只顯示一張圖片,其他隱藏。經過計算偏移量利用定時器實現自動播放,或經過手動點擊事件切換圖片。

實踐:http://www.mwcxs.top/%E8%BD%AE%E6%92%AD/index.html

更正(更正日期於2018.10.29)爲:https://www.mwcxs.top/static/mybs/lunbo/index.html

 

歡迎訪問:

一、雲商城isv系統http://isv.suningcloud.com/mpisv-web/index

 二、雲商城消費者門戶http://www.suningcloud.com/promotion/index/experience_center.html

 

追加於2018.10.29

完整的代碼

<!DOCTYPE html>
<html>

    <head>
        <meta charset="utf-8" />
        <title></title>
        <style type="text/css">
            * {
                margin: 0;
                padding: 0;
                text-decoration: none;
            }
            
            body {
                padding: 20px;
            }
            
            #container {
                position: relative;
                width: 600px;
                height: 400px;
                border: 3px solid #333;
                overflow: hidden;
            }
            
            #list {
                position: absolute;
                z-index: 1;
                width: 4200px;
                height: 400px;
            }
            
            #list img {
                float: left;
                width: 600px;
                height: 400px;
            }
            
            #buttons {
                position: absolute;
                left: 250px;
                bottom: 20px;
                z-index: 2;
                height: 10px;
                width: 100px;
            }
            
            #buttons span {
                float: left;
                margin-right: 5px;
                width: 10px;
                height: 10px;
                border: 1px solid #fff;
                border-radius: 50%;
                background: #333;
                cursor: pointer;
            }
            
            #buttons .on {
                background: orangered;
            }
            
            .arrow {
                position: absolute;
                top: 180px;
                z-index: 2;
                display: none;
                width: 40px;
                height: 40px;
                font-size: 36px;
                font-weight: bold;
                line-height: 35px;
                text-align: center;
                color: #fff;
                background-color: RGBA(0, 0, 0, .3);
                cursor: pointer;
            }
            
            .arrow:hover {
                background-color: RGBA(0, 0, 0, .7);
            }
            
            #container:hover .arrow {
                display: block;
            }
            
            #prev {
                left: 20px;
            }
            
            #next {
                right: 20px;
            }
        </style>
    </head>

    <body>
        <div id="container">
            <div id="list" style="left: -600px;">
                <img src="img/5.png" alt="1" />
                <img src="img/1.png" alt="1" />
                <img src="img/2.png" alt="2" />
                <img src="img/3.png" alt="3" />
                <img src="img/4.png" alt="4" />
                <img src="img/5.png" alt="5" />
                <img src="img/1.png" alt="5" />
            </div>
            <div id="buttons">
                <span index="1" class="on"></span>
                <span index="2"></span>
                <span index="3"></span>
                <span index="4"></span>
                <span index="5"></span>
            </div>
            <a href="javascript:;" id="prev" class="arrow">&lt;</a>
            <a href="javascript:;" id="next" class="arrow">&gt;</a>
        </div>

    </body>

</html>

<script>
    window.onload = function() {
        var list = document.getElementById('list');
        var prev = document.getElementById('prev');
        var next = document.getElementById('next');

        function animate(offset) {
            /*獲取的是style.left,是相對左邊獲取距離,因此第一張圖後style.left都爲負值,
            且style.left獲取的是字符串,須要用parseInt()取整轉化爲數字。*/
            var newLeft = parseInt(list.style.left) + offset;
            list.style.left = newLeft + 'px';
            if(newLeft < -3000) {
                list.style.left = -600 + 'px';
            }
            if(newLeft > -600) {
                list.style.left = -3000 + 'px';
            }
        }
        /*須要定位到按鈕的樣式*/
        var buttons = document.getElementById('buttons').getElementsByTagName('span');
        var index = 1;

        function buttonShow() {
            /*console.log(buttons.length);*/
            /*清除以前的樣式*/
            for(var i = 0; i < buttons.length; i++) {
                if(buttons[i].className === 'on') {
                    buttons[i].className = '';
                }
            }
            /*數組從0開始,temp從-1開始*/
            buttons[index - 1].className = 'on';
        }
        /*上一步*/
        prev.onclick = function() {
                index = index - 1;
                if(index < 1) {
                    index = 5;
                }
                buttonShow();
                animate(600);
            }
            /*下一步*/
        next.onclick = function() {
                index = index + 1;
                if(index > 5) {
                    index = 1;
                }
                buttonShow();
                animate(-600);
            }
            /*自動循環播放*/
        var timer;

        function play() {
            timer = setInterval(function() {
                next.onclick();
            }, 1500)
        }
        play();
        /*鼠標放上(離開)對應輪播暫停(播放)*/
        var container = document.getElementById('container');

        function stop() {
            clearInterval(timer);
        }
        container.onmouseover = stop;
        container.onmouseout = play;

        /*小圓點的點擊事件*/
        for(var i = 0; i < buttons.length; i++) {
            /*使用當即函數*/
            (function(i) {
                buttons[i].onclick = function() {
                    console.log(i);
                    /*偏移量的獲取:獲取鼠標的小圓點的位置,用this把index綁定到對象buttons[i]上*/
                    /*因爲index是自定義屬性,須要用到getAttribute()這個dom的2級方法,去獲取自定義的index屬性*/
                    var clickIndex = parseInt(this.getAttribute('index'));
                    var offset = 600 * (index - clickIndex);
                    animate(offset);
                    index = clickIndex;
                    buttonShow();
                }
            })(i)
        }
    }
</script>

線上地址更換了,如今:https://www.mwcxs.top/static/mybs/lunbo/index.html

相關文章
相關標籤/搜索