小白成長日記:一步一步寫個輪播圖插件

最近在這裏看了一篇關於面試的文章《回顧本身三次失敗的面試經歷》,做者三次倒在了輪播圖上。囧,因此我也寫個輪播圖看看。
此次是用jQuery寫的,由於最近一直在研究jQuery插件的寫法,因此用jQuery寫的,並且我發現,我vue用太多,徹底不熟悉dom操做,之後仍是要多多用用jQuery和原生jscss

獻給小白們:jQuery插件開發精品教程,讓你的jQuery提高一個臺階html

html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>slide</title>
    <script src="http://upcdn.b0.upaiyun.com/libs/jquery/jquery-2.0.2.min.js"></script>
    <script src="jquery.js"></script>
    <style>
    *{
        margin:0;
        padding: 0;
    }
    li{
        list-style: none;
    }
    ul{
        display: flex;
        position: relative;
    }
    .contain{
        width: 600px;
        overflow: hidden;
        position: relative;
    }
    ol{
        position: absolute;
        bottom:10px;
        display: flex;
        justify-content: center;
        width: 100%;
    }
    ol li{
        width: 10px;
        height: 10px;
        border-radius: 50%;
        background-color: #f60;
        margin:0 2px;
    }
    .conActive{
        background-color: #fff;
    }
</style>
</head>
<body>
    <div id="slide">
        <div class="contain">
            <ul>
                <li><img src="img/img11.jpg" alt=""></li>
                <li><img src="img/img21.jpg" alt=""></li>
                <li><img src="img/img33.jpg" alt=""></li>
                <li><img src="img/img39.jpg" alt=""></li>
                <li><img src="img/img55.jpg" alt=""></li>
            </ul>
        </div>
    </div>
    <style>
        $(function() {
            $(".contain").Slide()
        })
    </style>
</body>
</html>

首先的插件的大致結構以下vue

;(function($, window, document, undefined) {
    var pluginName = "Slide",
    defaults = {
        
    };
    function Slide(element, options) {
        this.element = element;
        this.settings = $.extend({}, defaults, options);
        this._defaults = defaults;
        this._name = pluginName;
        this.version = 'v1.0.0';
        this.init();
    }
    Slide.prototype = {
        init: function() {
            
        }       
    };
    $.fn[pluginName] = function(options) {
        this.each(function() {
            if (!$.data(this, "plugin_" + pluginName)) {
                $.data(this, "plugin_" + pluginName, new Slide(this, options));
            }
        });
        return this;
    };
})(jQuery, window, document);

接下來就是輪播圖的大體邏輯了。jquery

主體

初始化,動起來

由簡入繁的寫,第一步是考慮怎麼讓輪播圖動起來
圖片描述git

輪播圖在網頁上大體是這個樣子的,只有一張暴露在視野內,其餘的在視野外,用overflow:hidden隱藏就行。
那動起來就很是簡單github

$(element).animate({right:index*this.width+'px'}, 1000)//jQuery中animate方法

初始化的話,咱們須要計算整個ul的長度,獲取單個li的長度。面試

丐中丐版輪播圖

;(function($, window, document, undefined) {
    var pluginName = "Slide",
    defaults = {
        
    };
    function Slide(element, options) {
        this.element = element;
        this.width = $(this.element).find('ul li img')[0].width;//圖片寬度
        this.length = $(this.element).find('ul li').length//輪播數量
        this.settings = $.extend({}, defaults, options);
        this._defaults = defaults;
        this._name = pluginName;
        this.version = 'v1.0.0';
        this.init();
    }
    Slide.prototype = {
        init: function() {
            let index=1//索引
            const content = $(this.element).find('ul');//獲取ul
            content.css('width',this.width*this.length);//計算長度
            this.autoplay(content,index)
        },
        autoplay: function(content,index) {
            const _this=this;
            timer=setInterval(function(){
                $(content).animate({right:index*this.width+'px'}, 1000)
                index++
            },2000)
        }       
    };
    $.fn[pluginName] = function(options) {
        this.each(function() {
            if (!$.data(this, "plugin_" + pluginName)) {
                $.data(this, "plugin_" + pluginName, new Slide(this, options));
            }
        });
        return this;
    };
})(jQuery, window, document);

到這裏,輪播圖已經在一張圖一張圖的往右跑了,輪播圖的邏輯就這麼多。可是別人的輪播圖都會回頭啊,這個輪播圖跑着跑着白屏了。接下來就讓他回頭,利用聲明的index實現。app

乞丐版輪播圖

;(function($, window, document, undefined) {
    var pluginName = "Slide",
    defaults = {
        
    };
    function Slide(element, options) {
        this.element = element;
        this.width = $(this.element).find('ul li img')[0].width;//圖片寬度
        this.length = $(this.element).find('ul li').length//輪播數量
        this.settings = $.extend({}, defaults, options);
        this._defaults = defaults;
        this._name = pluginName;
        this.version = 'v1.0.0';
        this.init();
    }
    Slide.prototype = {
        init: function() {
            let index=1//索引
            const content = $(this.element).find('ul');//獲取ul
            content.css('width',this.width*this.length);//計算長度
            this.autoplay(content,index)
        },
        autoplay: function(content,index) {
            const _this=this;
            timer=setInterval(function(){
                $(content).animate({right:index*this.width+'px'}, 1000)
                index===this.length-1?index=0:index++//若是索引到了this.length-1,說明到了最後一張圖片,咱們將index調爲0,下一次運行時,ul的樣式就會歸位,這樣就成功回頭
            },2000)
        }       
    };
    $.fn[pluginName] = function(options) {
        this.each(function() {
            if (!$.data(this, "plugin_" + pluginName)) {
                $.data(this, "plugin_" + pluginName, new Slide(this, options));
            }
        });
        return this;
    };
})(jQuery, window, document);

這邊已經實現了一個像模像樣的輪播圖了,但在尾->首切換的時候違和感太嚴重了,咱們須要的是平滑過渡,曾經我絞盡腦汁想不出辦法,而後花了半分鐘上網搜索到了答案,下次不再瞎想了。
圖片描述dom

如上圖,在輪播圖最後複製一個輪播圖第一張,當劃到最後一個slide1時,再當即將ul位置復原,切換到第一個slide1,咱們覺得劃到了第一個slide1,這樣就能實現平滑的過渡。jquery插件

無產階級輪播圖

;(function($, window, document, undefined) {
    var pluginName = "Slide",
    defaults = {
        
    };
    function Slide(element, options) {
        this.element = element;
        this.width = $(this.element).find('ul li img')[0].width;//圖片寬度
        this.length = $(this.element).find('ul li').length//輪播數量
        this.settings = $.extend({}, defaults, options);
        this._defaults = defaults;
        this._name = pluginName;
        this.version = 'v1.0.0';
        this.init();
    }
    Slide.prototype = {
        init: function() {
            let index=1//索引
            const content = $(this.element).find('ul');//獲取ul
            content.css('width',this.width*this.length);//計算長度
            this.autoplay(content,index)
        },
        autoplay: function(content,index) {
            const _this=this;
            timer=setInterval(function(){
                $(content).animate({right:index*_this.width+'px'}, 1000)
                if(index===_this.length){
                    $(content).animate({right:0+'px'}, 0)//將ul回覆到原位
                    index=1//index重置爲1(這裏是1,恢復到函數剛開始的索引)
                }else{
                    index++
                }
            },2000)
        },
        creat: function(){
            $($(this.element).find('ul li')[0]).clone().appendTo($(this.element).find('ul'))
        },//克隆第一個li再添加到ul       
    };
    $.fn[pluginName] = function(options) {
        this.each(function() {
            if (!$.data(this, "plugin_" + pluginName)) {
                $.data(this, "plugin_" + pluginName, new Slide(this, options));
            }
        });
        return this;
    };
})(jQuery, window, document);

好的,完整版的輪播圖就完成了,若是對輪播圖沒有任何須要,大體就是這樣了。但咱們網站中的輪播圖多種多樣,用過插件的小夥伴也知道,不少輪播圖能自定義參數來開啓不一樣的功能,例如強大的swiper插件。接下來咱們就來實現一些自定義的功能。

貧農版輪播圖

自定義參數:輪播間隔時間,輪播分頁小點

;(function($, window, document, undefined) {
    var pluginName = "Slide",
    defaults = {//默認參數
        pagination:true,//默認開啓輪播分頁小點
        interval:2000//默認間隔時間2s
    };//這裏不明白的小白朋友們麻煩去通讀上面推薦的jquery插件的寫法,就會明白
    function Slide(element, options) {
        this.element = element;
        this.width = $(this.element).find('ul li img')[0].width;//圖片寬度
        this.length = $(this.element).find('ul li').length//輪播數量
        this.settings = $.extend({}, defaults, options);
        this._defaults = defaults;
        this._name = pluginName;
        this.version = 'v1.0.0';
        this.init();
    }
    Slide.prototype = {
        init: function() {
            let index=1;
            this.creat();
            this.settings.pagination?this.pagination():''//若是設置了pagination:true,建立小點
            this.addStyle(0)//給第一個小點添加樣式
            const content = $(this.element).find('ul');//獲取ul
            content.css('width',this.width*this.length);//計算長度
            this.autoplay(content,index)
        },
        autoplay: function(content,index) {
            const _this=this
            timer=setInterval(function(){
                console.log(index*this.width)
                $(content).animate({right:index*_this.width+'px'}, 1000)
                if(index===_this.length){
                    $(content).animate({right:0+'px'}, 0)
                    index=1
                }else{
                    index++
                }
                _this.addStyle(index-1)//index變化,致使小點樣式變化
            },this.settings.ininterval)//將自定義時間傳入
        },
        creat: function(){
            $($(this.element).find('ul li')[0]).clone().appendTo($(this.element).find('ul'))
        },
        pagination: function(index){
            let ol="<ol></ol>"
            $(this.element).append(ol)
            let li="<li></li>"
            for(i=1;i<this.length;i++){
                $(this.element).find('ol').append(li)
            }//建立分頁小點             
        },
        addStyle: function(index){
            let active=$(this.element).find('ul li')[index]
            $(active).addClass('active').siblings().removeClass('active')
            if(this.settings.pagination){
                let conActive=$(this.element).find('ol li')[index]
                $(conActive).addClass('conActive').siblings().removeClass('conActive')
            }
        }//給活動的輪播圖和小點添加樣式      
    };
    $.fn[pluginName] = function(options) {
        this.each(function() {
            if (!$.data(this, "plugin_" + pluginName)) {
                $.data(this, "plugin_" + pluginName, new Slide(this, options));
            }
        });
        return this;
    };
})(jQuery, window, document);

接下來就是改變下調用

$(function() {
    $(".contain").Slide({
            pagination:false,
            interval:5000
        })
    })

這裏就起做用了。
若是再有其餘的功能,只須要往裏面一步一步添加函數就能夠了,好比前進後退按鈕,好比一次滾動多張圖片。

小結

之因此要本身寫一寫這些小demo,是爲了有助於咱們更好的使用別人的代碼。並非全部人寫的代碼或者插件都適合小白使用,好比better-scroll,這是一個vue的滾動插件,大多數人使用了以後發現滾動不了,去做者github提issue,實際上是他們並不懂滾動的原理。我以前也是摸索了做者的實例才成功使用的,但這個插件並不僅是滾動,還有其餘應用,好比手機端聯繫人列表插件,我徹底搞不懂這是怎麼實現的,天然也使用不起來。最近我就用vue本身實現了一個手機端聯繫人列表,很是很是之簡單,一個函數搞定,難點在於html的合理佈局,因此沒有發到這裏,有興趣的小夥伴能夠去github看下。
知其然,更要知其因此然。這樣才能慢慢進步,不然只能靠搬運插件混生活了。

源碼

https://github.com/yuyeqianxu...

相關文章
相關標籤/搜索