Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

DateTime控件制作(ChromeOnly)

  虽然HTML5自己有带DateTime控件,但是我觉得那个非常难用。特别是它弹出一个月历来让用户选择,这是非常不人性化的设计。如果用户知道自己需要填写的日期时间,也许更喜欢手动输入年月日。即使只是对日期时间的微修改,用鼠标滚轮也比其它方式好。
  于是我自己设计了个看似普通文本条的DateTime控件(实际上它就是一个普通的文本框),它可以以普通文本框的方式操作。但额外的,点击年月日时分秒任意一个字段时会直接选中该字段,这时可以使用键盘输入。最后还有使用鼠标滚轮对数据微调的功能,只要把鼠标指针放在某个字段上(可以不需要点击),滚动滚轮就可以修改相应字段的值。下面是演示代码
<!DOCTYPE html>
<base href="http://www.web-tinker.com/files/" />
<script src="widget-datetime.js"></script>
<widget-datetime value="2014-7-9"></widget-datetime>
  其中widget-datetime.js在这里 //widget-datetime.js
var HTMLWidgetDatetime=document.registerElement("widget-datetime",{
  prototype:{
    createdCallback:function(){
      var that=this;
      var root=this.webkitCreateShadowRoot();
      var input=document.createElement("input");
      root.appendChild(input);
      var surface=document.createElement("div");
      root.appendChild(surface);
      setTimeout(function(){
        surface.style.top=input.offsetTop+"px";
        surface.style.left=input.offsetLeft+"px";
      });
      Object.defineProperty(this,"value",{
        get:function(){return input.value;},
        set:function(e){
          var l=input.selectionStart,r=input.selectionEnd;
          input.value=new Date(typeof e=="number"?e:parse(e)||0)
            .toISOString().replace(/T/," ").replace(/\..+/,"")
            .replace(/^.*(\d{4})(?=-)/,"$1");
          if(root.activeElement==input)
            input.selectionStart=l,input.selectionEnd=r;
          resetSurface();
        }
      });
      that.value=that.getAttribute("value");
      //直接修改
      (function(){
        var old;
        input.addEventListener("focus",function(){
          old=input.value;
        });
        input.addEventListener("change",function(){
          var v=parse(this.value);
          that.value=isNaN(v)?old:v;
        });
      })();
      //滚轮修改
      (function(){
        surface.addEventListener("mousedown",function(e){
          var range=getRange(e),moved=false;
          surface.style.visibility="hidden";
          document.addEventListener("mouseup",mouseup);
          document.addEventListener("mousemove",mousemove);
          function mouseup(e){
            if(!moved&&range)
              input.selectionEnd=range[1],
              input.selectionStart=range[0];
            document.removeEventListener("mouseup",mouseup);
            surface.style.visibility="visible";
          };
          function mousemove(){moved=true;};
        });
        surface.addEventListener("wheel",function(e){
          var p=getRange(e),s,v=input.value;
          if(!p)return;
          if(/^\d+$/.test(s=v.slice(p[0],p[1])))
            s=s*1+(e.shiftKey?10:1)*e.wheelDelta/120;
          if(s<0)s=0;
          that.value=v.substr(0,p[0])+s+v.substr(p[1]);
        });
        function getRange(e){
          var i=0,o=e.target,l,r,v;
          if(o.parentNode!=surface)return;
          while(o=o.previousSibling)i++;
          l=i,r=i,v=input.value;
          if(/\D/.test(v[i]))return;
          while(/\d/.test(v[l-1]))l--;
          while(/\d/.test(v[r]))r++;
          return [l,r];
        };
      })();
      //样式
      this.style.display="inline-block";
      var style=document.createElement("style");
      style.textContent=(function(){/*
        div,input {
          margin:0px;border:1px solid #CCC;
          padding:3px;font:14px/16px Consolas;height:16px;
          outline:none;width:11em;text-align:center;
        }
        div {position:absolute;opacity:0;}
      */}).toString().replace(/^.+?\/\*|\*\/\}\s*$/g,"");
      root.appendChild(style);
      function parse(e){
        e=(e+"").match(/\d+/g)||[];
        if(e[0]<30)e[0]=+e[0]+2000;
        if(1 in e)e[1]-=1;
        return Date.UTC.apply(Date,e);
      };
      function resetSurface(){
        surface.innerHTML="";
        for(var span,i=0,s=input.value;i<s.length;i++)
          span=document.createElement("span"),
          span.textContent=s[i],surface.appendChild(span);
      };
    },__proto__:HTMLElement.prototype
  }
});
网名:
3.84.186.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^