本文目录

JavaScript 模块化开发日历控件

🌙
手机阅读
本文目录结构

封在一个方法里,可以根据项目的不同,再次重构;

没有做点击面板以外的地方,自动关闭选择面板;这个功能在研究事件源的时候;再做(事件委托模式),因为这个比较重要,需要单独的去写;

1

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>日历控件</title>
    <style>
        body{-webkit-user-select: none;}
        #calendar{width: 200px;padding: 5px;background: orange;}
        #calendar h6{font-size: 16px;background: blue;color:#FFF;height: 30px;line-height: 30px;text-align: center; padding: 0;margin: 0;position: relative;cursor: pointer;}
        #calendar h6 span{width: 35px;height: 30px;position: absolute;top:0;}
        #calendar h6 span.prev{left: 0;background: #000000;}
        #calendar h6 span.next{right: 0;background: #000000;}
        #calendar ul{padding: 0;margin: 0;list-style: none;overflow: hidden;}
        #calendar ul li{float: left;width: 26px;height: 26px;background: darkgreen;line-height: 25px;text-align: center;border: 1px solid #CCC;cursor: pointer;}
    </style>
</head>
<body>
<div id="calendar">
    <h6><span class="prev">上</span>2015年9月<span class="next">下</span></h6>
    <ul>
        <li>日</li>
        <li>一</li>
        <li>二</li>
        <li>三</li>
        <li>四</li>
        <li>五</li>
        <li>六</li>
    </ul>
    <ul>
        <li>12</li>
        <li>12</li>
        <li>12</li>
    </ul>
</div>
</body>
</html>
<script>

</script>

2

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>日历控件</title>
    <style>
        body{-webkit-user-select: none;}
        #calendar{width: 200px;padding: 5px;background: orange;}
        #calendar h6{font-size: 16px;background: blue;color:#FFF;height: 30px;line-height: 30px;text-align: center; padding: 0;margin: 0;position: relative;cursor: pointer;}
        #calendar h6 span{width: 35px;height: 30px;position: absolute;top:0;}
        #calendar h6 span.prev{left: 0;background: #000000;}
        #calendar h6 span.next{right: 0;background: #000000;}
        #calendar ul{padding: 0;margin: 0;list-style: none;overflow: hidden;}
        #calendar ul li{float: left;width: 26px;height: 26px;background: darkgreen;line-height: 25px;text-align: center;border: 1px solid #CCC;cursor: pointer;color: #FFF;}
    </style>
</head>
<body>
<div id="calendar">
    <h6><span class="prev">上</span>2015年9月<span class="next">下</span></h6>
    <ul>
        <li>日</li>
        <li>一</li>
        <li>二</li>
        <li>三</li>
        <li>四</li>
        <li>五</li>
        <li>六</li>
    </ul>
</div>
</body>
</html>
<script>
    var calendar=document.getElementById("calendar"),
            oUl=document.createElement("ul"),
            currentDate=new Date,//当前的日.不让它变;
            activeDate=new Date;//活动的日期,这个是不断变的;
    activeDate.setDate(1);//活动显示日期的日设置为1号;
    var diff=1-activeDate.getDay();//获取1号前面还有几个LI用来漏出上一个月的日期;;
    activeDate.setDate(diff);//算出日历的起始日期;确定后再循环出后面的日期就可以了;算出这个月要往前退几步;
    for(var i=0;i<42;i++){
        var oLi=document.createElement("li"),
                date=activeDate.getDate();
        oLi.innerHTML=date;//表示当前的这个LI是几号;
        activeDate.setDate(date+1);//让日期对象往后走一天;然后再下一次循环的时候,赋值给oLi.innerHTML
        oUl.appendChild(oLi);
    }
    calendar.appendChild(oUl);

















</script>

3

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>日历控件</title>
    <style>
        body{-webkit-user-select: none;}
        #calendar{width: 200px;padding: 5px;background: orange;}
        #calendar h6{font-size: 16px;background: blue;color:#FFF;height: 30px;line-height: 30px;text-align: center; padding: 0;margin: 0;position: relative;cursor: pointer;}
        #calendar h6 span{width: 35px;height: 30px;position: absolute;top:0;}
        #calendar h6 span.prev{left: 0;background: #000000;}
        #calendar h6 span.next{right: 0;background: #000000;}
        #calendar ul{padding: 0;margin: 0;list-style: none;overflow: hidden;}
        #calendar ul li{float: left;width: 26px;height: 26px;background: darkgreen;line-height: 25px;text-align: center;border: 1px solid #CCC;cursor: pointer;color: #FFF;}
    </style>
</head>
<body>
<div id="calendar">
    <h6>
        <span class="prev">上</span>
        <div>XXXX年XX月</div>
        <span class="next">下</span>
    </h6>
    <ul>
        <li>日</li>
        <li>一</li>
        <li>二</li>
        <li>三</li>
        <li>四</li>
        <li>五</li>
        <li>六</li>
    </ul>
</div>
</body>
</html>
<script>
    var calendar=document.getElementById("calendar"),
            title=document.getElementsByTagName("h6")[0].getElementsByTagName("div")[0],
            oUl=document.createElement("ul"),
            currentDate=new Date,//当前的日.不让它变;
            activeDate=new Date;//活动的日期,这个是不断变的;
    activeDate.setDate(1);//活动显示日期的日设置为1号;
    var diff=1-activeDate.getDay();//获取1号前面还有几个LI用来漏出上一个月的日期;
    var month=activeDate.getMonth();
    title.innerHTML=activeDate.getFullYear()+"年"+(month+1)+"月";
    activeDate.setDate(diff);//算出日历的起始日期;确定后再循环出后面的日期就可以了;算出这个月要往前退几步;
    for(var i=0;i<42;i++){
        var oLi=document.createElement("li"),
                date=activeDate.getDate();
        oLi.innerHTML=date;//表示当前的这个LI是几号;
        oUl.appendChild(oLi);
        if(activeDate.getMonth()!=month){
            oLi.style.color="#CCC"
        }
        activeDate.setDate(date+1);//让日期对象往后走一天;然后再下一次循环的时候,赋值给oLi.innerHTML


    }
    calendar.appendChild(oUl);

</script>

4

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>日历控件</title>
    <style>
        body{-webkit-user-select: none;}
        #calendar{width: 200px;padding: 5px;background: orange;position: absolute;z-index: 100;}
        #calendar h6{font-size: 16px;background: blue;color:#FFF;height: 30px;line-height: 30px;text-align: center; padding: 0;margin: 0;position: relative;cursor: pointer;}
        #calendar h6 span{width: 35px;height: 30px;position: absolute;top:0;}
        #calendar h6 span.prev{left: 0;background: #000000;}
        #calendar h6 span.next{right: 0;background: #000000;}
        #calendar ul{padding: 0;margin: 0;list-style: none;overflow: hidden;}
        #calendar ul li{float: left;width: 26px;height: 26px;background: darkgreen;line-height: 25px;text-align: center;border: 1px solid #CCC;cursor: pointer;color: #FFF;}
    </style>
</head>
<body>
<input type="text" value="" onfocus="creatCalendar(this)" >
<div style="width: 200px;height: 200px; background: #CCC;"></div>
</body>
</html>
<script>
    function creatCalendar(ele){
        var obj=offset(ele);//为了确定日历控件出现的位置;
        var x=obj.left;
        var y=obj.top+ele.offsetHeight+5;
        if(!document.getElementById("calendar")){
            var calendar=document.createElement("div");
            calendar.id="calendar";
            calendar.style.left=x+"px";//确定日历控件出现的位置,需要用到绝对定位,并且z-index要设施;
            calendar.style.top=y+"px";
            var h6=document.createElement("h6");
            var prev=document.createElement("span");
            var title=document.createElement("div");
            var next=document.createElement("span");
            prev.className="prev";
            next.className="next";
            prev.innerHTML="上";
            next.innerHTML="下";

            calendar.appendChild(h6);
            h6.appendChild(prev);
            h6.appendChild(title);
            h6.appendChild(next);
            document.body.appendChild(calendar);

            oUl=document.createElement("ul");
            var currentDate=new Date;//当前的日.不让它变;
            var currentYear=currentDate.getFullYear();
            var currentMonth=currentDate.getMonth();
            prev.onclick=function(){active(--currentMonth)};
            next.onclick=function(){active(++currentMonth)};
            active(currentMonth);
            calendar.appendChild(oUl);
        }
        function active(m){
            oUl.innerHTML="";
            var activeDate=new Date(currentYear,m);//活动的日期,这个是不断变的;
            activeDate.setDate(1);//活动显示日期的日设置为1号;
            var diff=1-activeDate.getDay();//获取1号前面还有几个LI用来漏出上一个月的日期;
            var month=activeDate.getMonth();
            title.innerHTML=activeDate.getFullYear()+"年"+(month+1)+"月";
            activeDate.setDate(diff);//算出日历的起始日期;确定后再循环出后面的日期就可以了;算出这个月要往前退几步;
            for(var i=0;i<42;i++){
                var oLi=document.createElement("li"),
                        date=activeDate.getDate();
                oLi.innerHTML=date;//表示当前的这个LI是几号;
                oUl.appendChild(oLi);
                if(activeDate.getMonth()!=month){
                    oLi.style.color="#CCC"
                }
                activeDate.setDate(date+1);//让日期对象往后走一天;然后再下一次循环的时候,赋值给oLi.innerHTML
            }
        }
        function offset(ele){
            var l=ele.offsetLeft;
            var t=ele.offsetTop;
            var p=ele.offsetParent;
            while(p){
                if(window.navigator.userAgent.indexOf("MISE 8")>-1){
                    l+= p.offsetLeft;
                    t+= p.offsetTop;
                }else{
                    l+= p.offsetLeft+ p.clientLeft;
                    t+= p.offsetTop+ p.clientTop;
                }
                p= p.offsetParent;
            }
            return {left:l,top:t}
        }
    }
</script>

5

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>日历控件</title>
    <style>
        body{-webkit-user-select: none;}
        #calendar{width: 200px;padding: 5px;background: orange;position: absolute;z-index: 100;}
        #calendar h6{font-size: 16px;background: blue;color:#FFF;height: 30px;line-height: 30px;text-align: center; padding: 0;margin: 0;position: relative;cursor: pointer;}
        #calendar h6 span{width: 35px;height: 30px;position: absolute;top:0;}
        #calendar h6 span.prev{left: 0;background: #000000;}
        #calendar h6 span.next{right: 0;background: #000000;}
        #calendar ul{padding: 0;margin: 0;list-style: none;overflow: hidden;}
        #calendar ul li{float: left;width: 26px;height: 26px;background: darkgreen;line-height: 25px;text-align: center;border: 1px solid #CCC;cursor: pointer;color: #FFF;}
    </style>
</head>
<body>
<input type="text" value=" " onfocus="creatCalendar(this)" class="j-select-data">
<div style="width: 200px;height: 200px; background: #CCC;"><a href="http://taobao.fm/archives/1461">查看本页实现原理</a></div>
<br/>
<br/>
<br/>
<br/>
<br/>
<p>没有做点击面板以外的地方,自动关闭选择面板;这个功能在研究事件源的时候;再做(事件委托模式),因为这个比较重要,需要单独的去写;</p>
<br/>
<br/>
<br/>
<br/>
<input type="text" value=" " onfocus="creatCalendar(this)">

</body>
</html>
<script>
    function creatCalendar(ele){
        var obj=offset(ele);//为了确定日历控件出现的位置;
        var x=obj.left;
        var y=obj.top+ele.offsetHeight+5;
        if(!document.getElementById("calendar")){
            var calendar=document.createElement("div");
            calendar.id="calendar";
            calendar.style.left=x+"px";//确定日历控件出现的位置,需要用到绝对定位,并且z-index要设施;
            calendar.style.top=y+"px";
            var h6=document.createElement("h6");
            var prev=document.createElement("span");
            var title=document.createElement("div");
            var next=document.createElement("span");
            prev.className="prev";
            next.className="next";
            prev.innerHTML="上";
            next.innerHTML="下";

            calendar.appendChild(h6);
            h6.appendChild(prev);
            h6.appendChild(title);
            h6.appendChild(next);
            document.body.appendChild(calendar);
/*            ele.onblur= function () {//如果需要鼠标离开日历界面,或者失去焦点再关闭,用到事件委托;思路参考;http://broszhu.com/works/xiaomiNavigation/index.html
                document.body.removeChild(calendar);
                calendar=null;
            };*/

            oUl=document.createElement("ul");
            var currentDate=new Date;//当前的日.不让它变;
            var currentYear=currentDate.getFullYear();
            var currentMonth=currentDate.getMonth();
            prev.onclick=function(){active(--currentMonth)};
            next.onclick=function(){active(++currentMonth)};
            active(currentMonth);
            calendar.appendChild(oUl);
        }
        function active(m){
            oUl.innerHTML="";
            var activeDate=new Date(currentYear,m);//活动的日期,这个是不断变的;
            activeDate.setDate(1);//活动显示日期的日设置为1号;
            var diff=1-activeDate.getDay();//获取1号前面还有几个LI用来漏出上一个月的日期;
            var month=activeDate.getMonth();
            title.innerHTML=activeDate.getFullYear()+"年"+(month+1)+"月";
            activeDate.setDate(diff);//算出日历的起始日期;确定后再循环出后面的日期就可以了;算出这个月要往前退几步;
            for(var i=0;i<42;i++){
                var oLi=document.createElement("li"),
                        date=activeDate.getDate();
                oLi.innerHTML=date;//表示当前的这个LI是几号;
                oLi.dateValue=activeDate.getFullYear()+"-"+(activeDate.getMonth()+1)+"-"+date;
                oLi.onclick= function () {
                    ele.value=this.dateValue;
                    document.body.removeChild(calendar);
                    calendar=null;
                };
                oUl.appendChild(oLi);
                if(activeDate.getMonth()!=month){
                    oLi.style.color="#CCC"
                }
                activeDate.setDate(date+1);//让日期对象往后走一天;然后再下一次循环的时候,赋值给oLi.innerHTML
            }
        }
        function offset(ele){//计算任意DOM元素距离文档的左或上的绝对偏移
            var l=ele.offsetLeft;
            var t=ele.offsetTop;
            var p=ele.offsetParent;
            while(p){
                if(window.navigator.userAgent.indexOf("MISE 8")>-1){//判断IE8的方法
                    l+= p.offsetLeft;
                    t+= p.offsetTop;
                }else{
                    l+= p.offsetLeft+ p.clientLeft;
                    t+= p.offsetTop+ p.clientTop;
                }
                p= p.offsetParent;
            }
            return {left:l,top:t}
        }
    }
</script>

AXIHE / 精选资源

浏览全部教程

面试题

学习网站

前端培训
自己甄别

前端书籍

关于朱安邦

我叫 朱安邦,阿西河的站长,在杭州。

以前是一名平面设计师,后来开始接接触前端开发,主要研究前端技术中的JS方向。

业余时间我喜欢分享和交流自己的技术,欢迎大家关注我的 Bilibili

关注我: Github / 知乎

于2021年离开前端领域,目前重心放在研究区块链上面了

我叫朱安邦,阿西河的站长

目前在杭州从事区块链周边的开发工作,机械专业,以前从事平面设计工作。

2014年底脱产在老家自学6个月的前端技术,自学期间几乎从未出过家门,最终找到了满意的前端工作。更多>

于2021年离开前端领域,目前从事区块链方面工作了