面向对象实例--常用组件

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阅读 159,117评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,328评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,839评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,007评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,384评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,629评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,880评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,593评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,313评论 1 243
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,575评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,066评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,392评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,052评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,082评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,844评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,662评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,575评论 2 270

推荐阅读更多精彩内容