原生js日期插件实现

网上有很多实现日期插件的方法,不过扩展了些,相对于项目实用方法。

html结构及其配置参数

引入css,引入js即可,值得兴奋的事是用原生js编写的,所以量级方面会小一点,当然这个插件并不是很炫,不过确实很实用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>日期插件</title>
    <link rel="stylesheet" href="css/date1.2.css" />
</head>
<body>
<input type="text" id="ipt" style="margin: 50px;width:50%;height: 30px;" />
<input type="text" id="ipt1" style="margin-left:500px "/>
<script src="js/TaoTaoDate.js"></script>
<script>
    TaoTaodate({
        dateId:"ipt", //input 上面的id
        skin:"red",   //皮肤配置参数
        interval:" - " // 分隔符参数配置
    })
    TaoTaodate({
        dateId:"ipt1",
        interval:" /\ "
    })
</script>
</body>
</html>

CSS代码

这个css需要处理一下默认样式,默认样式使用网上相对简单标准的样式初始化代码

body{
    font-family: 'PingFangSC-Regular', 'PingFang SC';
    font-style: normal;
    font-weight: 400;
    font-size: 13px;
    /*font-family:"Lantinghei SC", "Open Sans", Arial, "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", "STHeiti", "WenQuanYi Micro Hei", SimSun, sans-serif;*/
}
html,body{
    background-repeat: no-repeat;
    -webkit-text-size-adjust:none;
}
.clearfix:after {
    content: "." ;
    display: block ;
    height: 0 ;
    clear: both ;
    visibility: hidden ;
}
a{
    text-decoration:none;
    outline: none;
}
li{
    list-style-type:none;
}
img{
    width: 100%;
    max-width: 100%;
    /*vertical-align: top;*/
    font-size:0.5rem;
}

html, body, h1, h2, h3, p, span, a, div, ol, ul, li, dl, dt, dd, table, tbody, tfoot, thead, tr, th, td, input, textarea, form, select {
    padding: 0;
    margin: 0;
    /*font-family: "Lantinghei SC", "Open Sans", Arial, "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", "STHeiti", "WenQuanYi Micro Hei", SimSun, sans-serif;*/
    box-sizing:border-box;
}
h1, h2, h3 {
    font-size: 100%;
}
button{
    -webkit-appearance:none;
    -moz-appearance:none;
    appearance:none;
    outline:none;
    border:1px solid #ccc;
}
input[type=button],input[type=submit]{
    -webkit-appearance:none;
    outline:none;
}
/**
插件重要样式
 */
div.date_div_containers{
    width: auto;
    height: auto;
    position: fixed;
    top: 0;
    left: 0;
    display: none;
}
table.date_table_tables{
    border: 1px solid #eeeeee;
    border-collapse: collapse;

}
table.date_table_tables thead th{
    width: 40px;
    height: 30px;
    line-height: 30px;
    text-align: center;
    border: 1px solid #eee;
    background: #eee;
    color: #FFFFFF;
}
table.date_table_tables tbody td{
    width: 40px;
    height: 30px;
    color: #333333;
    line-height: 30px;
    text-align: center;
    border: 1px solid #eeeeee;
    background: #fff;
    cursor: pointer;

}
select.date_select_selts{
    width: 25%;
    height: 25px;
    border: 1px solid #eeeeee;
}

JavaScript 代码

这块算是比较激动人心了吧?注释写的挺详细的,就不多说了。

/**
 * Created by 涛 on 2017/4/18.
 */
function TaoDate(obj) {
    var _this =this;
    //扩展参数配置
    this.bgColor=obj["skin"]?obj["skin"]:"#eee";
    this.interval=obj["interval"]?obj["interval"]:"-";
    //渲染头部,以及表格头节点
   this.setDateDom(obj["dateId"]);
   //初始化select内容
   this.sElect(obj["dateId"]);
   //渲染表格盒子
    this.dateBox(obj["dateId"]);
    //扩展换肤功能
    this.dateSkin(this.bgColor,obj["dateId"]);
    //讲日期放在table盒子当中
    this.Tab(obj["dateId"]);
    //规定日期盒子位置函数
    this.inputOffset(obj["dateId"]);
    var myDiv =document.getElementById(obj["dateId"]+"_divId");
    var divArray =document.getElementsByClassName("date_div_containers");
    var ipt =document.getElementById(obj["dateId"]);
    ipt.setAttribute("readonly","readonly");
    //当配置好这个控件,显示本地年月日
    var iptVal =new Date();
    ipt.value=iptVal.getFullYear()+this.interval+(iptVal.getMonth()+1)+
        this.interval+iptVal.getDate();
    //============================事件区域=================
    //点击输入框
    ipt.onfocus=function(){
        //保证每次只能有一个input能出现日期盒子
        for(var i =0;i<divArray.length;i++){
            divArray[i].style.display='none';
        }
        myDiv.style.display="block";
    }
    //年份change事件
    myDiv.getElementsByClassName("date_select_selts")[0].onchange=function(){
        _this.Tab(obj["dateId"]);
    }
    //月份change事件
    myDiv.getElementsByClassName("date_select_selts")[1].onchange=function(){
        _this.Tab(obj["dateId"]);
    }
    //事件委托点击被选中的日期,进入输入框中
    myDiv.onclick=function(ev){
        for(var i =0;i<myDiv.getElementsByTagName("td").length;i++){
            myDiv.getElementsByTagName("td")[i].style.backgroundColor="#fff";
        }
        ev =window.event||ev; //获取事件源
        var target =ev.target||ev.srcElement; //捕捉事件
        if(target.nodeName.toLowerCase()==="td"&&target.innerHTML!=""){
            ipt.value=myDiv.getElementsByClassName("date_select_selts")[0].value+_this.interval
            +myDiv.getElementsByClassName("date_select_selts")[1].value+_this.interval
            +target.innerHTML;
            target.style.backgroundColor=_this.bgColor;
            //点完就让消失
            myDiv.style.display='none';
        }
        return false;//阻止冒泡阻止默认事件
    }
    //事件委托点击页面消失
    document.onclick=function(ev){
        ev =window.event||ev; //获取事件源
        var target =ev.target||ev.srcElement; //捕捉事件
       if(target.nodeName.toLowerCase()=="html")
           for(var i =0;i<divArray.length;i++){
               divArray[i].style.display='none';
           }
    }

}
/**
 * 获取某一年的某一月1号是星期几
 * @param year
 * @param month
 * @returns {number}
 */
TaoDate.prototype.getone = function (year, month) {
    return new Date(year, month - 1, 1).getDay();
};
/**
 * 获取某一个年某一月有多少天
 * @param year
 * @param month
 * @returns {number}
 */
TaoDate.prototype.getDaysInOneMonth = function (year, month) {
    month = parseInt(month, 10); //强转成数字
    var d = new Date(year, month, 0);  //这个是都可以兼容的
    return d.getDate();
};
/**
 * 通过input id属性搭建结构属性
 * @param id
 */
TaoDate.prototype.setDateDom = function(id) {
    var week =["周一","周二","周三","周四","周五","周六","周日"];
    var oDiv =document.createElement("div");
    oDiv.setAttribute("class","date_div_containers");
    oDiv.setAttribute("id",id+"_divId");
    var Asel =document.createElement("select");
    Asel.setAttribute("class","date_select_selts");
    Asel.setAttribute("id",id+"_date_select_selts");
    oDiv.appendChild(Asel);
    var spanHtml =document.createElement("span");
    spanHtml.setAttribute("class","date_span_text");
    spanHtml.appendChild(document.createTextNode("    年     "))
    oDiv.appendChild(spanHtml);
    var Asel =document.createElement("select");
    Asel.setAttribute("class","date_select_selts");
    Asel.setAttribute("id",id+"_date_select_selts1");
    oDiv.appendChild(Asel);
    var spanHtml =document.createElement("span");
    spanHtml.setAttribute("class","date_span_text");
    spanHtml.appendChild(document.createTextNode("    月   "))
    oDiv.appendChild(spanHtml);
    var tables =document.createElement("table");
    tables.setAttribute("class","date_table_tables");
    tables.setAttribute("id",id+"_date_table_tables");
    tables.appendChild(document.createElement("thead"));
    for(var i =0;i<7;i++){
        tables.getElementsByTagName("thead")[0].appendChild(document.createElement("th"));
        tables.getElementsByTagName("thead")[0].getElementsByTagName("th")[i].innerHTML=week[i];
    }
    tables.appendChild(document.createElement("tbody"));
    oDiv.appendChild(tables);
    document.body.appendChild(oDiv);

}
/**
 * 年份、月份 (起始年份/起始月份 -- 结束年份/结束月份)
 * @param beginNum 起始
 * @param closeNum  结束
 * @returns {string}
 */
TaoDate.prototype.forVal=function(beginNum,closeNum){
    var str ='';
    for(var i =beginNum;i<=closeNum;i++){
        str+="<option>"+i+"</option>";
    }
    return str;
}
/**
 * 初始化年份,月份!
 */
TaoDate.prototype.sElect=function(id){
    var sel= document.getElementById(id+"_divId").getElementsByClassName("date_select_selts");
    sel[0].innerHTML=this.forVal(1990,2099);
    sel[1].innerHTML=this.forVal(1,12);
    var date =new Date();
    sel[0].value=date.getFullYear();
    sel[1].value=date.getMonth()+1;
}
/**
 * 通过div上id创建表格
 * @param id
 */
TaoDate.prototype.dateBox=function(id){
    var div1 =document.getElementById(id+"_date_table_tables");
    for(var i =0;i<6;i++){
        var aTR = document.createElement("tr");
        div1.tBodies[0].appendChild(aTR);
        for(var j =0;j<7;j++){
            var aTd =document.createElement("td");
            div1.tBodies[0].rows[i].appendChild(aTd);
        }
    }
}
TaoDate.prototype.Tab=function(id){
    var tds = document.getElementById(id+"_date_table_tables")
        .getElementsByTagName("td");
    var date =new Date();
    //渲染前先清空,避免上次与本次内容冲突
    for(var j=0;j<tds.length;j++){
        tds[j].innerHTML="";
        tds[j].style.backgroundColor='';
    }
    var sel= document.getElementById(id+"_divId").getElementsByClassName("date_select_selts");
    var year =this.getone(sel[0].value,sel[1].value);
    year=year-1;
    year =year==-1?6:year;
    var month =this.getDaysInOneMonth(sel[0].value,sel[1].value);
    for(var i=year;i<month+year;i++){
        tds[i].innerHTML=i-year+1;
    }
    tds[date.getDate()+year-1].style.backgroundColor=this.bgColor;
}
/**
 * 日期盒子规定在哪个位置
 * @param id 传入id
 * @param num  传入input高度
 */
TaoDate.prototype.inputOffset=function(id){
    var TaoDate =document.getElementById(id);
    var oDiv =document.getElementById(id+"_divId");
    oDiv.style.left=TaoDate.offsetLeft+"px"
    oDiv.style.top=TaoDate.offsetTop+TaoDate.offsetHeight+"px";
}
TaoDate.prototype.dateSkin=function(skin,id){
    var ths =document.getElementById(id+"_date_table_tables").getElementsByTagName("th");
    var tds =document.getElementById(id+"_date_table_tables").getElementsByTagName("td");
    for(var i =0;i<ths.length;i++){
        ths[i].style.background=skin;
        ths[i].style.borderColor=skin;

    }
    for(var j =0;j<tds.length;j++){
        tds[j].style.borderColor=skin;
    }

}
//主函数调用方法
function TaoTaodate(json){
    return new TaoDate(json);
}

总结:

插件开发方式有很多,其实应该再插件里面写一个默认参数对象的。用传入的对象参数覆盖,默认参数,而且应该多多抽象一些方法,如可以单独抽象出document.getElementById方法,追其根本,有意无意模仿了一波jquery,不过量级上肯定是小的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,080评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,422评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,630评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,554评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,662评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,856评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,014评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,752评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,212评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,541评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,687评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,347评论 4 331
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,973评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,777评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,006评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,406评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,576评论 2 349

推荐阅读更多精彩内容