datepicker 原生js实现

点击选择,DatePicker组件开发教程-慕课网icon-default.png?t=L892https://www.imooc.com/video/14518分为:

ui,render,事件,日期的操作

源码如下:

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="style.css">
  <style>
    .datepicker{
      border: 1px solid #ccc;
      border-radius: 4px;
      padding: 5px;
      height: 24px;
      line-height: 24px;
      width: 230px;
    }
    .datepicker:focus{
      outline: 0 none;
      border: 1px solid #1abc9c;
    }
  </style>
</head>
<body style="margin: 10px; height: 1000px;">
  <div>
    <div style="margin: 30px;">
      <input type="text" class="datepicker">
    </div>
  </div>
  <script src="date.js"></script>
  <script src="main.js"></script>
  <script>
    datepicker.init('.datepicker')
  </script>
</body>
</html>

style.css

.ui-datepicker-wrapper{
  width: 240px;
  font-size: 16px;
  color: #666;
  box-shadow: 2px 2px 8px 2px rgba(128, 128, 128, .3);
  display: none;
  position: absolute;
}
.ui-datepicker-wrapper-show{
  display: block;
}
.ui-datepicker-wrapper .ui-datepicker-header{
  padding: 0 20px;
  height: 50px;
  line-height: 50px;
  text-align: center;
  background: #f0f0f0;
  border-bottom: 1px solid #ccc;
  font-weight: bold;
}
.ui-datepicker-wrapper .ui-datepicker-btn{
  font-family: serif;
  font-size: 20px;
  width: 20px;
  height: 50px;
  line-height: 50px;
  color: #1abc9c;
  text-align: center;
  cursor: pointer;
  text-decoration: none;
}
.ui-datepicker-wrapper .ui-datepicker-prev-btn{
  float: left;
}
.ui-datepicker-wrapper .ui-datepicker-next-btn{
  float: right;
}
.ui-datepicker-wrapper .ui-datepicker-body table{
  width: 100%;
  border-collapse: collapse;
}
.ui-datepicker-wrapper .ui-datepicker-body th,
.ui-datepicker-wrapper .ui-datepicker-body td{
  height: 30px;
  text-align: center;
}
.ui-datepicker-wrapper .ui-datepicker-body th{
  font-size: 12px;
  height: 40px;
  line-height: 49px;
}
.ui-datepicker-wrapper .ui-datepicker-body td{
  border: 1px solid #f0f0f0;
  font-size: 10px;
  cursor: pointer;
}

main.js

(function(){
  var datepicker = window.datepicker;
  var monthData;
  var $wrapper;
  datepicker.buildUi = function(year, month){
    monthData = datepicker.getMonthData(year, month);
    var html = '<div class="ui-datepicker-header">'+
    '<a href="#" class="ui-datepicker-btn ui-datepicker-prev-btn">&lt;</a>'+
    '<a href="#" class="ui-datepicker-btn ui-datepicker-next-btn">&gt;</a>'+
    '<span class="ui-datepicker-curr-month">'+monthData.year+'-'+monthData.month+'</span>'+
  '</div>'+
  '<div class="ui-datepicker-body">'+
    '<table>'+
      '<thead>'+
        '<tr>'+
          '<th>一</th>'+
          '<th>二</th>'+
          '<th>三</th>'+
          '<th>四</th>'+
          '<th>五</th>'+
          '<th>六</th>'+
          '<th>七</th>'+
        '</tr>'+
      '</thead>'+
      '<tbody>';
      for(var i=0; i<monthData.days.length; i++){
        var date = monthData.days[i];
        if(i%7===0){
          html+='<tr>'
        }
        html += '<td data-date="'+date.date+'">'+date.showDate+'</td>'
        if(i%7===6){
          html+='</tr>'
        }
      }
      html+='</tbody>'+
    '</table>'+
  '</div>';
  return html;
  };
  datepicker.render = function(direction){
    var year, month;
    if(monthData){
      year  = monthData.year;
      month = monthData.month;
    }
    if(direction==='prev')month--;
    if(direction==='next')month++;
    var html = datepicker.buildUi(year, month);
    // $dom.innerHTML=html;
    $wrapper = document.querySelector('.ui-datepicker-wrapper');
    if(!$wrapper){
      $wrapper = document.createElement('div');
      $wrapper.className='ui-datepicker-wrapper';
    }
    $wrapper.innerHTML = html;
    document.body.appendChild($wrapper);
  }
  datepicker.init = function(input){
    datepicker.render();
    var $input = document.querySelector(input);
    var isOpen = false;
    $input.addEventListener('click', function(){
      if(isOpen) {
        $wrapper.classList.remove('ui-datepicker-wrapper-show')
        isOpen=false;
      }else{
        $wrapper.classList.add('ui-datepicker-wrapper-show')
        // 根据input的位置,设置日期的位置
        var left = $input.offsetLeft;
        var top = $input.offsetTop;
        var height = $input.offsetHeight;
        $wrapper.style.top=top+height+2+"px";
        $wrapper.style.left=left+"px";
        isOpen=true;
      }
    }, false);
    // 事件绑定在 $wrapper ,这样就不会因为重新渲染而失效
    $wrapper.addEventListener('click', function(e){
      var $target = e.target;
      if(!$target.classList.contains('ui-datepicker-btn')){
        return
      }
      // 上一月
      if($target.classList.contains('ui-datepicker-next-btn')){
        datepicker.render('next');
      }else if($target.classList.contains('ui-datepicker-prev-btn')){
        datepicker.render('prev');
      }
    }, false);
    $wrapper.addEventListener('click', function(e){
      var $target = e.target;
      if($target.tagName.toLowerCase() !== 'td')return;
      // data-开头的数据在dataset里
      var date = new Date(monthData.year, monthData.month-1, $target.dataset.date);
      $input.value = format(date);
      $wrapper.classList.remove('ui-datepicker-wrapper-show')
      isOpen=false;
    }, false)
  };
  function format(date){
    var ret = '';
    var padding = function(num){
      if(num<=9)return '0'+num;
      return num;
    }
    ret += date.getFullYear() + '-';
    ret += padding(date.getMonth()+1) + '-';
    ret += padding(date.getDate());
    return ret;
  }
})();

date.js

(function(){
  var datepicker = {};
  datepicker.getMonthData = function(year, month) {
    var ret = [];
    // 当前日期
    if(!year || !month) {
      var today = new Date();
      year = today.getFullYear();
      month = today.getMonth() + 1;  // 真实月份
    }
    var firstDay = new Date(year, month-1, 1);  // 这个月的第一天
    var firstDayWeekDay = firstDay.getDay();  // 这一天是星期几
    if(firstDayWeekDay === 0) firstDayWeekDay = 7;  // 

    year = firstDay.getFullYear();
    month = firstDay.getMonth()+1;

    var lastDayOfLastMonth = new Date(year, month-1, 0);  // 上个月的最后一天
    var lastDateOfLastMonth = lastDayOfLastMonth.getDate();  // 此天的日期

    var preMonthDayCount = firstDayWeekDay - 1;

    var lastDay = new Date(year, month, 0);
    var lastDate = lastDay.getDate();

    for(var i=0; i<7*6; i++){
      var date = i - preMonthDayCount + 1;  // 
      var showDate = date;
      var thisMonth = month;
      // 上一月
      if(date<=0){
        thisMonth = month - 1;
        showDate = lastDateOfLastMonth + date;
      }else if(date > lastDate) {
        // 下一月
        thisMonth = month + 1
        showDate  =showDate - lastDate
      }
      if(thisMonth===0)thisMonth=12;
      if(thisMonth===13)thisMonth=1;
      ret.push({
        month: thisMonth,
        date:date,
        showDate:showDate
      });
    }
    return {
      year: year,
      month: month,
      days:ret
    };
  }
  window.datepicker = datepicker;
})();

Guess you like

Origin blog.csdn.net/qq_27009517/article/details/120368615