物件導向例項--常用元件

weixin_33670713發表於2017-04-24

1.物件導向:

  1. 易維護: 採用物件導向思想設計的結構,可讀性高,由於繼承的存在,即使改變需求,那麼維護也只是在區域性模組,所以維護起來是非常方便和較低成本的。
  2. 質量高: 在設計時,可重用現有的,在以前的專案的領域中已被測試過的類使系統滿足業務需求並具有較高的質量。
  3. 效率高: 在軟體開發時,根據設計的需要對現實世界的事物進行抽象,產生類。使用這樣的方法解決問題,接近於日常生活和自然的思考方式,勢必提高軟體開發的效率和質量。
  4. 易擴充套件: 由於繼承、封裝、多型的特性,自然設計出高內聚、低耦合的系統結構,使得系統更靈活、更容易擴充套件,而且成本較低。

2.Tab元件

3407000-ed23fb14b940cd31.gif
20170418_165846.gif

用jquery實現tab效果並不難,來看下主要程式碼:


 $('.ct>li').on('click',function(){
       var $this =$(this)
        var index = $(this).index();//被點中的下標 .index()jquery方法;
        console.log(index);
        $this.siblings().removeClass('active');
        $this.addClass('active')      

      $this.parents('.wrap').find('.panel').removeClass('active')
      $this.parents('.wrap').find('.panel').eq(index).addClass('active')

     
    })

如何用物件導向寫成元件?

function Tab(ct){  //寫一個建構函式;
      this.ct = ct;
      this.init();//init()初始化
      this.bind();//bind()//繫結事件處理;
  }
 Tab.prototype.init = function (){ //給原型上幫定初始化函式;
      this.tabLis = this.ct.querySelectorAll('.ct>li')//選中所有的li
      this.panels = this.ct.querySelectorAll('.panel')//選中所有的panel

  }
Tab.prototype.bind = function (){
      var _this =this ;//儲存this指向 
      this.tabLis.forEach(function(tabli){//迴圈所有的的li,
          tabli.onclick = function(e){//當點選時
          var  target = e.target;//被點中的的目標li;
          var index  = [].indexOf.call(_this.tabLis,target)//借用陣列方法;獲取被點中的li下標;
          _this.tabLis.forEach(function(li){//迴圈所有的的li,
                 li.classList.remove('active');//迴圈所有的的li,去掉active
          })

![20170424_000601.gif](http://upload-images.jianshu.io/upload_images/3407000-940252b56661b894.gif?imageMogr2/auto-orient/strip)
          target.classList.add('active');//給點中的li加上 active
          _this.panels.forEach(function(panel){//迴圈所有的的panel,
                 panel.classList.remove('active')//迴圈所有的的panel,去掉active
          })
          _this.panels[index].classList.add('active')//給對應li小標的panel加上active

          }
      })
  }
     new Tab(document.querySelectorAll('.wrap')[0])
     new Tab(document.querySelectorAll('.wrap')[1])
     new Tab(document.querySelectorAll('.wrap')[2])
//完成後只需new出建構函式的物件就可以了;
3407000-e801efbfa838f1c0.gif
20170418_171027.gif

3. 輪播元件

3407000-d7b0de4635c9a1bc.gif
20170418_172359.gif

用jquery實現輪播效果,來看下主要程式碼:

      var $imgCt =$('.img-ct'),
             $preBtn = $('.btn-pre'),
             $nextBtn = $('.btn-next'),
             $bullet  = $('.bullet');
           
       

        var $firstImg = $imgCt.find('li').first(),
            $lastImg = $imgCt.find('li').last();

        var pageIndex = 0; //第幾個頁的變數;
        var imgLength =$imgCt.children().length;  //獲取在克隆前有多少張圖片    
        var isAnimate = false;//防止重複點選

        $imgCt.prepend($lastImg.clone())//把最後一個圖clone一次新增到第一張的前面;
        $imgCt.append($firstImg.clone())//把最前一個圖clone一次新增到最後一張的後面;  

        $imgCt.width($firstImg.width()*$imgCt.children().length)  //設定ul的寬度     
        $imgCt.css({'left':'-'+$firstImg.width()+'px'})//把第一張圖放入可視區域

    auto()
     $preBtn.on('click',function(e){
         e.preventDefault()//阻止頁面重新整理
         playPre()
     })
     
     $nextBtn.on('click',function(e){
         e.preventDefault()
         playNext()
     })
     
     $bullet.find('li').on('click',function(e){
         e.preventDefault()
         var idx = $(this).index();
        if(idx>pageIndex){
            playNext(idx-pageIndex)
        }else if(idx<pageIndex){
            playPre(pageIndex-idx)
        }
      
     })

//以上是輪播的實現思想,下面完成效果的幾個函式

        
       function playNext(idx){
          var  idx = idx ||1
           if(isAnimate) return
           isAnimate = true;
           $imgCt.animate({
               left:'-='+($firstImg.width()*idx)
           },function(){
               pageIndex= pageIndex+idx;
               if(pageIndex === imgLength){//如果頁數=圖片的最後一個,就讓圖片回到第一張;即data-index=0;
                   $imgCt.css({'left':'-'+$firstImg.width()+'px'})
                   pageIndex = 0;
               }
               isAnimate =false;
                setBullet()
           })

       }


       function playPre(idx){
            var  idx = idx ||1
            if(isAnimate) return
           isAnimate = true;
           $imgCt.animate({
               left:'+='+$firstImg.width()*idx
           },function(){
               pageIndex=pageIndex-idx;
               if(pageIndex < 0 ){
                   $imgCt.css({'left':'-'+imgLength*$firstImg.width()+'px'})
                   pageIndex = imgLength - 1;
               }
                isAnimate =false;
                 setBullet()
           })
       }



        function setBullet(){//小圖示函式
            $bullet.children()
                    .removeClass('active')
                    .eq(pageIndex)
                    .addClass('active')
            }


    function auto(){
        var lock = setInterval(function(){
              playNext()
        },3000)
    }

如何用物件導向寫成元件?

function Carousel($ct){
            this.$ct = $ct;
            this.init();//初始化
            this.bind();//事件處理
            this.auto();//自動播放函式
        }//與Tab原理一樣寫一個建構函式

 Carousel.prototype.init = function(){//給原型上幫定初始化函式

             var $imgCt =this.$imgCt = this.$ct.find('.img-ct'),
             $preBtn =this.$preBtn = this.$ct.find('.btn-pre'),
             $nextBtn =this.$nextBtn=this.$ct.find('.btn-next'),
             $bullet  = this.$bullet= this.$ct.find('.bullet');

      var $firstImg =this.$firstImg= $imgCt.find('li').first(),
            $lastImg =this.$lastImg= $imgCt.find('li').last();

//這裡注意下 其他函式要用的變數要用this.

              this.pageIndex = 0; //第幾個頁的變數;
              this.imgLength =$imgCt.children().length;  //獲取在克隆前有多少張圖片    
              this.isAnimate = false;//防止重複點選


              
        $imgCt.prepend($lastImg.clone())//把最後一個圖clone一次新增到第一張的前面;
        $imgCt.append($firstImg.clone())//把最前一個圖clone一次新增到最後一張的後面;  

        $imgCt.width($firstImg.width()*$imgCt.children().length)  //設定ul的寬度     
        $imgCt.css({'left':'-'+$firstImg.width()+'px'})//把第一張圖放入可視區域

        }

Carousel.prototype.bind = function(){
            var _this = this;//儲存this;
                  this.$preBtn.on('click',function(e){
                    e.preventDefault()//阻止頁面重新整理
                      _this.playPre()//this指定的是按鈕所以要用儲存起來的_this;下面的一樣
                 })
     
                this.$nextBtn.on('click',function(e){
                    e.preventDefault()
                     _this.playNext()
                })
                 this.$bullet.find('li').on('click',function(e){
                      e.preventDefault()
                        var idx = $(this).index();
                        if(idx> _this.pageIndex){
                            _this.playNext(idx- _this.pageIndex)
                        }else if(idx< _this.pageIndex){
                            _this.playPre( _this.pageIndex-idx)
                        }
                    
                    })

        }

下面四個函式都繫結到原型上,實現效果 注意this的指向;與上面一樣;

  Carousel.prototype.playNext = function(idx){
              var _this = this;
               var  idx = idx ||1
                if(this.isAnimate) return
                this.isAnimate = true;
                this.$imgCt.animate({
                    left:'-='+(this.$firstImg.width()*idx)
                },function(){
                    _this.pageIndex= _this.pageIndex+idx;
                    if(_this.pageIndex === _this.imgLength){//如果頁數=圖片的最後一個,就讓圖片回到第一張;即data-index=0;
                        _this.$imgCt.css({'left':'-'+_this.$firstImg.width()+'px'})
                        _this.pageIndex = 0;
                    }
                    _this.isAnimate =false;
                        _this.setBullet()
                })

        }
        Carousel.prototype.playPre = function(idx){
            var _this = this;
               var  idx = idx ||1
                if(this.isAnimate) return
                this.isAnimate = true;
                this.$imgCt.animate({
                    left:'+='+this.$firstImg.width()*idx
                },function(){
                    _this.pageIndex=_this.pageIndex-idx;
                    if(_this.pageIndex < 0 ){
                        _this.$imgCt.css({'left':'-'+_this.imgLength*_this.$firstImg.width()+'px'})
                        _this.pageIndex = _this.imgLength - 1;
                    }
                        _this.isAnimate =false;
                        _this.setBullet()
                })

        }
        Carousel.prototype.setBullet = function (){
             this.$bullet.children()
                    .removeClass('active')
                    .eq(this.pageIndex)
                    .addClass('active')
            

        }
        Carousel.prototype.auto = function(){
            var _this = this;
                var lock = setInterval(function(){
                _this.playNext()
            },3000)

//最後根據需要new出建構函式的物件就可以了
        new Carousel($('.carousel').eq(0));
        new Carousel($('.carousel').eq(1));
        new Carousel($('.carousel').eq(2));
3407000-1ba29c87de053177.gif
20170418_174238.gif

4. 輪播的二次封裝

程式碼基本沒變化;
var Carouse = (function(){

        return {
                Toinit:function($ct){
                    $ct.each(function(index,node){
                         new _Carousel($(node));
                    })
                   
                }
            }
})()  //寫一個立刻執行函式,返回Toinit函式new出物件;把上面的程式碼放入這個立刻執行函式,注意名字不用起重複;

   var Carousel = (function(){
                    function _Carousel($ct){//建構函式
                    this.$ct = $ct;
                    this.init();
                    this.bind();
                    this.auto();
                }
                _Carousel.prototype.init = function(){

                    var $imgCt =this.$imgCt = this.$ct.find('.img-ct'),
                    $preBtn =this.$preBtn = this.$ct.find('.btn-pre'),
                    $nextBtn =this.$nextBtn=this.$ct.find('.btn-next'),
                    $bullet  = this.$bullet= this.$ct.find('.bullet');

            var $firstImg =this.$firstImg= $imgCt.find('li').first(),
                    $lastImg =this.$lastImg= $imgCt.find('li').last();

                    this.pageIndex = 0; //第幾個頁的變數;
                    this.imgLength =$imgCt.children().length;  //獲取在克隆前有多少張圖片    
                    this.isAnimate = false;//防止重複點選


                    
                $imgCt.prepend($lastImg.clone())//把最後一個圖clone一次新增到第一張的前面;
                $imgCt.append($firstImg.clone())//把最前一個圖clone一次新增到最後一張的後面;  

                $imgCt.width($firstImg.width()*$imgCt.children().length)  //設定ul的寬度     
                $imgCt.css({'left':'-'+$firstImg.width()+'px'})//把第一張圖放入可視區域

                }
                _Carousel.prototype.bind = function(){
                    var _this = this;
                        this.$preBtn.on('click',function(e){
                            e.preventDefault()//阻止頁面重新整理
                            _this.playPre()
                        })
            
                        this.$nextBtn.on('click',function(e){
                            e.preventDefault()
                            _this.playNext()
                        })
                        this.$bullet.find('li').on('click',function(e){
                            e.preventDefault()
                                var idx = $(this).index();
                                if(idx> _this.pageIndex){
                                    _this.playNext(idx- _this.pageIndex)
                                }else if(idx< _this.pageIndex){
                                    _this.playPre( _this.pageIndex-idx)
                                }
                            
                            })

                }
                _Carousel.prototype.playNext = function(idx){
                    var _this = this;
                    var  idx = idx ||1
                        if(this.isAnimate) return
                        this.isAnimate = true;
                        this.$imgCt.animate({
                            left:'-='+(this.$firstImg.width()*idx)
                        },function(){
                            _this.pageIndex= _this.pageIndex+idx;
                            if(_this.pageIndex === _this.imgLength){//如果頁數=圖片的最後一個,就讓圖片回到第一張;即data-index=0;
                                _this.$imgCt.css({'left':'-'+_this.$firstImg.width()+'px'})
                                _this.pageIndex = 0;
                            }
                            _this.isAnimate =false;
                                _this.setBullet()
                        })

                }
                _Carousel.prototype.playPre = function(idx){
                    var _this = this;
                    var  idx = idx ||1
                        if(this.isAnimate) return
                        this.isAnimate = true;
                        this.$imgCt.animate({
                            left:'+='+this.$firstImg.width()*idx
                        },function(){
                            _this.pageIndex=_this.pageIndex-idx;
                            if(_this.pageIndex < 0 ){
                                _this.$imgCt.css({'left':'-'+_this.imgLength*_this.$firstImg.width()+'px'})
                                _this.pageIndex = _this.imgLength - 1;
                            }
                                _this.isAnimate =false;
                                _this.setBullet()
                        })

                }
                _Carousel.prototype.setBullet = function (){
                    this.$bullet.children()
                            .removeClass('active')
                            .eq(this.pageIndex)
                            .addClass('active')
                    

                }
                _Carousel.prototype.auto = function(){
                    var _this = this;
                        var lock = setInterval(function(){
                        _this.playNext()
                    },3000)
                }


            return {
                Toinit:function($ct){
                    $ct.each(function(index,node){
                         new _Carousel($(node));
                    })
                   
                }
            }
        })()

 Carousel.Toinit($('.carousel')); //new出頁面所有class= carousel的物件;
//與上面的第一種效果是一樣~

5. 曝光元件-懶載入

3407000-35e8bb72cdcad813.gif
20170418_175717.gif

用jquery實現tab效果並不難,來看下主要程式碼:

      check();//先載入出在可數去裡的圖片
        $(window).on('scroll', check)//當視窗滾動載入圖片

        function  check(){
            $('.container img').not('.load').each(function(){
                if(isShow($(this))){
                    show($(this))
                }
            })
        } 



        function show($imgs){//改變src的值;
            $imgs.each(function(){
                var imgUrl = $(this).attr('data-src');
                $(this).attr('src',imgUrl);
                $(this).addClass('load')
            })
        }


        function isShow($node){//判斷圖片是否出現在可視區裡
            var windowHeight = $(window).height(),
                scrollTop = $(window).scrollTop(),
                offsetTop = $node.offset().top,
                nodeHeight = $node.height();
            if(windowHeight+scrollTop>offsetTop && scrollTop< offsetTop+nodeHeight){
                return true;
            }else{
                return false;
            }     //scrollTop< offsetTop+nodeHeight瀏覽器上邊緣
                 //windowHeight+scrollTop>offsetTop瀏覽器下邊緣
        }

如何用物件導向寫成元件?

var Lazy =(function(){ //寫一個立即執行函式
     function Exposure($target,callback,isOnce){//建構函式
     this.$target = $target;
     this.callback = callback;
     this.isOnce = isOnce;
     this.hasShow = false; //用於判斷是否繼續執行
     this.bind();//事件繫結
     this.check();

 }

 Exposure.prototype.showImg = function($node){

     var imgUrl = $node.attr('data-src');
                 $node.attr('src',imgUrl);

 }
 Exposure.prototype.bind = function(){
     var _this = this;
     $(window).on('scroll', function(){
         _this.check();
     })

 }
 Exposure.prototype.check = function(){
      
      if(this.isOnce){// 如果傳入第3個引數就執行;
          if(this.isShow() && !this.hasShow){//如果兩個條件都成立執行;
              this.callback(this.$target)
              this.hasShow = true;
//這裡是為了構造的物件的callback函式執行一次還是多次
          }
      }else {// 如果沒有傳入第3個引數就執行;
           if(this.isShow()){
              this.callback(this.$target)
              
          }

      }
                      
 }
 Exposure.prototype.isShow = function(){
      
 var windowHeight = $(window).height(),
                scrollTop = $(window).scrollTop(),
                offsetTop = this.$target.offset().top,
                nodeHeight = this.$target.height();
            if(windowHeight+scrollTop>offsetTop && scrollTop< offsetTop+nodeHeight){
                return true;
            }else{
                return false;
            }  
 }  
  
            
    return {
        init :function($targets,callback){//多次執行callback;
            $targets.each(function(idx,target){
                new Exposure($(target),callback)
            })

        },
        one:function($target,callback){//執行一次callback;
            $target.each(function(idx,target){
                new Exposure($(target),callback,true)
            })
        }
    }
})()

 Lazy.one($('#hello'),function($node){
      $node.text($node.text()+'只加一次');
 })
 Lazy.init($('#world'),function($node){
      $node.text($node.text()+'加多次');
 })
Lazy.one($('.container img'),function($node){
     this.showImg($node);
})
3407000-6d33adc66934a5de.gif
20170418_181103.gif

6. Modal 元件

3407000-a91344dbf957d0c9.gif
20170424_000601.gif

如何用物件導向寫成元件? 看下主要的程式碼:

// 用模組定義的方式建立一個物件,把new Modal 的過程封裝到模組裡,這樣用這就可以直接通過Dialog.open()的方法呼叫
            var Dialog  =(function(){
                function Modal(){
                    this.createDialog();
                    this.bind();
                }

                Modal.prototype = {
                    defaults:{//設定初始引數
                        title:'',
                        message:'',
                        ShowCloseBtn:true,
                        ShowConfirmBtn:false,
                        onClose:function(){},
                        onConfirm:function(){}
                    },
                    open:function(opts){//當點選按鈕時傳入引數;
                        this.setOpts(opts);//設定引數;
                        console.log(this.opts);
                        this.setDialog();//設定Dialog
                        this.showDialog()//顯示Dialog
                    },
                     createDialog:function(){//建立Dialog
                        var tpl = '<div class="ct">'
                                  +  '<div class="cover"></div>'
                                  +  '<div class="dialog">'
                                  +    '<div class="dialog-head"><h3></h3><span class="btn-close">X</span></div>' 
                                  +    '<div class="dialog-content"></div>' 
                                  +    '<div class="dialog-footer"><a href="#" class="btn btn-close">取消</a> <a href="#" class="btn btn-confirm">確定</a></div>' 
                                  +  '</div>'
                                  +'</div>' ;
                         this.$ct  = $(tpl);  
                         $('body').append(this.$ct);       
                    },
                     bind:function(){
                        var _this = this;
                        _this.$ct.find('.btn-close').on('click',function(e){//當點選.btn-close時
                            e.preventDefault();//阻止預設事件;
                            _this.opts.onClose()
                            _this.hideDialog()
                        });
                         _this.$ct.find('.btn-confirm').on('click',function(e){
                            e.preventDefault();
                            _this.opts.onConfirm()
                            _this.hideDialog()
                        });
                    },
                   
                    setOpts:function(opts){
                        if(typeof opts === 'string'){//如果為字串;引數值變為
                            this.opts = $.extend({},this.defaults,{message:opts})//引數值變為一個新的物件
                        }else if (typeof opts === 'object'){//如果為物件
                            this.opts = $.extend({},this.defaults,opts);//引數值變為一個新的物件
                        }
                    },
                   
                    setDialog:function(){//設定Dialog的樣式
                        var $ct = this.$ct;
                        if(!this.opts.title){
                            $ct.find('.dialog-head').hide()
                        }else{
                             $ct.find('.dialog-head').show()
                        }
                        if(!this.opts.ShowCloseBtn){
                            $ct.find('.dialog-footer .btn-close').hide();
                        }else{
                             $ct.find('.dialog-footer .btn-close').show();
                        }
                        if(!this.opts.ShowConfirmBtn){
                            $ct.find('.dialog-footer .btn-confirm').hide();
                        }else{
                            $ct.find('.dialog-footer .btn-confirm').show();
                        }
                        $ct.find('.dialog-head h3').text(this.opts.title);
                        $ct.find('.dialog-content').html(this.opts.message);

                    },
                    showDialog:function(){
                        this.$ct.show()//Dialog顯示
                    },
                    hideDialog:function(){
                        this.$ct.hide()//Dialog隱藏
                    }
                };
                return  new Modal();
            })()

//通過傳入不同的引數;來改變dialog的樣式
            $('.open1').on('click',function(){
                Dialog.open('Welcome to the world of IT');
            })

            $('.open2').on('click',function(){
                Dialog.open('<a href="#">'+'百度'+'</a>');
            })

            $('.open3').on('click',function(){
                Dialog.open({
                    title:'World',
                    message:'Welcome to the world of IT',
                    ShowCloseBtn:true,
                    ShowConfirmBtn:true,
                    onClose:function(){
                        alert('close')
                    },
                    onConfirm:function(){
                        alert('確定')
                    }
                });
            })

          
            $('.open4').on('click',function(){
                var tpl = '<ul><li>'+'列表1'+'</li><li>'+'列表2'+'</li><li>'+'列表3'+'</li></ul>' 
                Dialog.open({
                    title:'World',
                    message:tpl,
                    ShowCloseBtn:true,
                    ShowConfirmBtn:true,
                    onClose:function(){
                        alert('close')
                    },
                    onConfirm:function(){
                        alert('確定')
                    }
                });
            })

              $('.open5').on('click',function(){   
                Dialog.open({
                    title:'World',
                    message:'Welcome to the world of IT',
                    ShowCloseBtn:false,
                    ShowConfirmBtn:false,
                    onClose:function(){
                        alert('close')
                    }
                
                });
            })

7.GoTop元件

3407000-c10f7df9dc499041.gif
20170413_002555.gif

如何用物件導向寫成元件? 看下主要的程式碼:

          var GoTop = function(ct,target){
              this.ct = ct;
              this.target = $('<div class="goTop">回到頂部</div>')
              this.target.css({
                    position:'fixed',
                    right:'100px',
                    bottom:'50px',
                    display:'none',
                    padding:'8px',
                    cursor:'pointer',
                    border:'1px solid',
                    borderRadius:'4px'
                })

          }
          GoTop.prototype.creatNode = function(){
              this.ct.append(this.target);
          }

          GoTop.prototype.bindEvent = function(){
              var _this = this;
              var $window = $(window);
            
              $window.on('scroll',function(){
                var $top = $window.scrollTop()
                  if($top>100){
                      _this.target.css('display','block')
                  }else{
                      _this.target.css('display','none')
                  }
              })
              this.target.on('click',function(){
                _this.ct.animate({
                   scrollTop : 0
               })
              })
          }

          var Gotop =new GoTop($('body'))
          Gotop.creatNode();
          Gotop.bindEvent();

8. 日曆元件

3407000-85d6eb8b50c5e755.gif
20170424_193724.gif

如何用物件導向寫成元件? 看下主要的程式碼:

function DatePicker($target) {
      //初始化當前日期
      this.init($target);

      //渲染日曆模板
      this.render();

      //設定模板裡面的資料
      this.setData();

      //繫結事件
      this.bind();
    }

    DatePicker.prototype = {

      init: function($target) {
        this.$target = $target;
        if (this.isValidDate($target.attr('date-init'))) {
          this.date = new Date($target.attr('date-init'));   //當前日期或者指定的要展示的日期
          this.watchDate = new Date($target.attr('date-init'));  //使用者在切換月份時所看到的日期,初始為當前日期
        } else {
          this.date = new Date();
          this.watchDate = new Date();
        }

      },

      render: function() {
        var tpl = '<div class="ui-date-picker" style="display:none">'
              +    '<div class="header"><span class="pre caret-left"></span><span class="cur header-date"></span><span class="next caret-right"></span></div>'
              +    '<table class="panel">'
              +      '<thead> <tr> <th>日</th> <th>一</th> <th>二</th> <th>三</th> <th>四</th> <th>五</th> <th>六</th> </tr> </thead>'
              +      '<tbody></tbody>'
              +   '</div>';
        this.$datepicker = $(tpl);
        this.$datepicker.insertAfter(this.$target)
                        .css({
                          'position': 'absolute',
                          'left': this.$target.offset().left,
                          'top': this.$target.offset().top + this.$target.height(true)
                        });
      },


      setData: function() {
        this.$datepicker.find('tbody').html('');

        var firstDay = this.getFirstDay(this.watchDate),
            lastDay = this.getLastDay(this.watchDate);

        var dateArr = [];

        for(var i = firstDay.getDay(); i>0; i--){
          var d = new Date( firstDay.getTime() - i*24*60*60*1000 );
          dateArr.push( {type:'pre', date:d} );
        }

        for(var j = 0; j< lastDay.getDate() - firstDay.getDate() + 1; j++){
          var d = new Date( firstDay.getTime() + j*24*60*60*1000 );
          dateArr.push( {type:'cur', date: d} );
        }

        for(var k = 1; k < 7 - lastDay.getDay(); k++ ){
          var d = new Date( lastDay.getTime() + k*24*60*60*1000 );
          dateArr.push( {type:'next', date: d}  )
        }

        this.$datepicker.find('.header-date').text(this.watchDate.getFullYear()+'年'+(this.watchDate.getMonth()+1)+'月');

        var tpl = '';
        for(var i=0;i<dateArr.length;i++){
          if(i%7 === 0){
            tpl = '<tr>' + tpl;
          }

          tpl += '<td class="';

          if(dateArr[i].type === 'pre'){
            tpl += 'pre-month';
          }else if(dateArr[i].type === 'cur'){
            tpl += 'cur-month';
          }else{
            tpl += 'next-month'
          }

          if(this.getYYMMDD(this.date) === this.getYYMMDD(dateArr[i].date)){
            tpl += ' cur-date';
          }
          tpl += '"';

          tpl += ' data-date="'+ this.getYYMMDD(dateArr[i].date) + '">';
          tpl += this.toFixed( dateArr[i].date.getDate()) + '</td>';


          if(i%7===6){
            tpl = tpl + '</tr>'
          }
        }

        this.$datepicker.find('tbody').html(tpl);
      },

      bind: function() {
        var self = this;
        this.$datepicker.find('.pre').on('click', function(){
          self.watchDate = self.getPreMonth(self.watchDate);
          self.setData();
        });
        this.$datepicker.find('.next').on('click', function(){
          self.watchDate = self.getNextMonth(self.watchDate);
          self.setData();
        });
        this.$datepicker.on('click', '.cur-month', function(){
          self.$target.val($(this).attr('data-date'))
          self.$datepicker.hide();
        });

        this.$target.on('click', function(e){
          e.stopPropagation();
          self.$datepicker.show();
        });

        //下面設定點選頁面其他部分隱藏 datepicker
        this.$datepicker.on('click', function(e){
          e.stopPropagation();
        });
        $(window).on('click', function(e){
          self.$datepicker.hide();
        })
      },

      isValidDate: function(dateStr) {
        return new Date(dateStr).toString() !== 'Invalid Date';
      },

      //獲取 date 所在月份的第一天的時間物件
      getFirstDay: function(date) {
        var year = date.getFullYear(),
          month = date.getMonth();

        return newDate = new Date(year, month, 1);
      },


      //獲取 date 所在月份最後一天的時間物件
      getLastDay: function(date) {
        var year = date.getFullYear(),
          month = date.getMonth();
          month++;

        if (month > 11) {
          month = 0;
          year++;
        }
        var newDate = new Date(year, month, 1);
        return new Date(newDate.getTime() - 1000 * 60 * 60 * 24);
      },


      //獲取date 上月1號時間物件
      getPreMonth: function(date){
        var year = date.getFullYear(),
          month = date.getMonth();

        month--;
        if (month < 0) {
          month = 11;
          year--;
        }
        return new Date(year, month, 1);
      },

      //獲取date 下月1號時間物件
      getNextMonth: function(date){
        var year = date.getFullYear(),
          month = date.getMonth();

        month++;
        if (month > 11) {
          month = 0;
          year++;
        }
        return new Date(year, month, 1);
      },


      getYYMMDD: function(date){
        var yy = date.getFullYear(),
            mm = date.getMonth()+1
        return date.getFullYear() + "/" + this.toFixed(date.getMonth() + 1) + "/" + this.toFixed(date.getDate());
      },

      //eg:  1 -> "01"  11 -> "11"
      toFixed: function(n){
        return (n+'').length === 1 ? ('0'+ n+'') : (n+'');
      }


    }



  // 建立物件的方式
  // $('.date-ipt').each(function(){
  //   new DatePicker($(this));
  // })




    //變成 jquery 外掛
    $.fn.datePicker = function() {
        this.each(function(){
          new DatePicker($(this));
        });
    };

    $('.date-ipt').datePicker();

希望對給位朋友有所幫助~~~

版權歸飢人谷--楠柒所有如有轉發請註明出處 謝謝~~

相關文章