面向對象實例--常用組件

1.面向對象:

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

2.Tab組件

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出構造函數的對象就可以了;
20170418_171027.gif

3. 輪播組件

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));
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. 曝光組件-懶加載

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);
})
20170418_181103.gif

6. Modal 組件

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組件

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. 日歷組件

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();

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

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

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,763評論 6 539
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,238評論 3 428
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,823評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,604評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,339評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,713評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,712評論 3 445
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,893評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,448評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,201評論 3 357
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,397評論 1 372
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,944評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,631評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,033評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,321評論 1 293
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,128評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,347評論 2 377

推薦閱讀更多精彩內容