使用HTC實現可用鼠標和鍵盤方向鍵調整的web時間控件

做軟件產品有時會遇到一個困惑,那就是如何樣式化(格式化)用戶的不規則輸入。以日期/時間的輸入爲例,前些年比較通用的做法是寫一段js代碼來判斷用戶的輸入是否正確,如果不正確就提示要以某某格式錄入,這種方式不僅費時費力,而且頗有馬後炮之嫌。如何能夠引導客戶按照正確的格式填寫我們所需的內容?我的看法是,可以剝奪用戶手動輸入的權利,只允許其在運行的範圍內選擇和調整。

我的初步設想是,對於一個用來進行時間輸入的文本框,當鼠標移入時,如果文本框爲空,則自動顯示0:00這一基準時間以供調整。當鼠標指向小時部分,向上轉動鼠標滾輪或按鍵盤的向上方向鍵,則小時數值增加,向下轉動鼠標滾輪或按鍵盤的向下方向鍵,則小時數值增加。同樣,也可以使用鼠標滾輪或者鍵盤方向鍵調整分鐘數值。此外,使用鍵盤的左右方向鍵可以在小時和分鐘兩部分之間切換。

爲此,寫了一堆js代碼來實現設想的功能,最終效果如下。

 

但是,麻煩很快就再次拜訪了。爲了使用這個功能,必須每次都爲該文本框添加onmouseover等很多事件,太煩。怎麼才能讓這個功能可方便的複用?HTC應該會是個好的主意。

有關HTML Component(HTC)的介紹可參見http://www.blueidea.com/tech/web/2003/1227.asp,藍色理想的這篇文章是我HTC入門的好導師,再此多謝了~~

使用了HTC後,頁面代碼得到了極大的簡化,只需引用樣式表dateinput.css併爲需要使用時間控件的文本框指定class爲dateinput即可。以下是dateinput.htm的內容。

 

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE> New Document </TITLE>
<link href="dateinput.css" rel="stylesheet" type="text/css">
</HEAD>
<BODY>
<INPUT TYPE="text" NAME="minute" value="" class="dateinput" readonly>
可以使用方向鍵或鼠標滾輪調整時間,呵呵
</BODY>
</HTML>

以下是dateinput.css的內容。 

.dateinput{
  behavior
:url(dateinput.htc)
}

 

 以下是dateinput.htc的內容。

 

<PUBLIC:ATTACH EVENT="onmousemove" oNEVENT="selTime()"/>
<PUBLIC:ATTACH EVENT="onmousewheel" oNEVENT="setTime()"/>
<PUBLIC:ATTACH EVENT="onkeydown" oNEVENT="setTimeByKB()"/>
<PUBLIC:ATTACH EVENT="onmouseout" oNEVENT="unselTime()"/>
<PUBLIC:METHOD NAME="regainTimeObj"/> 
<PUBLIC:METHOD NAME="setObjValue"/> 
<script language="javascript">
 
var h, m;
 
var sel;
 
var iValue;

 
function selTime(){
  
if(element.value == "")
   element.value 
= "0:00";
  
var bdy = document.body;
  regainTimeObj();
  
  
var baseLeft = bdy.leftMargin * 1  + element.offsetParent.offsetLeft * 1;
  
var hLeft = baseLeft + h.offsetLeft * 1;
  
var hRight = hLeft + h.boundingWidth;
  
var mLeft = baseLeft + m.offsetLeft * 1;
  
var mRight = mLeft + m.boundingWidth;
  
var mouseX = window.event.clientX;
  
if (mouseX >= hLeft && mouseX <= hRight){
   h.select();
   sel 
= 1;
  }

  
if (mouseX >= mLeft && mouseX <= mRight){
   m.select();
   sel 
= 2;
  }

 }


 
function unselTime(){
  h 
= null;
  m 
= null;
  sel 
= -1;
 }

 
function setTime(){
  
var step = parseInt(event.wheelDelta / 12010);
  
switch(sel){
   
case 1:
    setObjValue(h, step);
    
break;
   
case 2:
    setObjValue(m, step);
    
break;
  }

  
//return false;
 }

 
 
 
function setTimeByKB(){
  
var kc = event.keyCode;
  
switch(kc){
   
case 37//left
    switch(sel){
     
case 2:
      h.select();
      sel
--;
      
break;
     
default:
      
break;
    }

    
break;
   
case 38//up
    switch(sel){
     
case 1:
      setObjValue(h, 
1);
      
break;
     
case 2:
      setObjValue(m, 
1);
      
break;
     
default:
      
break;
    }

    
break;
   
case 39//right
    switch(sel){
     
case 1:
      m.select();
      sel
++;
      
break;
     
default:
      
break;
    }

    
break;
   
case 40//down
    switch(sel){
     
case 1:
      setObjValue(h, 
-1);
      
break;
     
case 2:
      setObjValue(m, 
-1);
      
break;
     
default:
      
break;
    }

    
break;
   
default:
    alert(
"請使用方向鍵或鼠標滾輪調整數字大小。");
    
break;
  }

  
return false;
 }

 
 
function regainTimeObj(){
  
var wholeText = element.value;
  
if(!wholeText || wholeText == "")
   wholeText 
= "0:00";
  
var pos = wholeText.indexOf(":");
  
var length = wholeText.length;
  h 
= element.createTextRange();
  m 
= element.createTextRange();
  h.moveEnd(
"character", pos - length);
  m.moveStart(
"character", pos + 1);
  
switch(sel){
   
case 1:
    h.select();   
    
break;
   
case 2:   
    m.select();
    
break;
  }

 }

 
 
 
function setObjValue(obj, step){
  iValue 
= parseInt(obj.text, 10+ step;
  
var maxValue = 59;
  
var addZero = false;
  
switch(obj){
   
case h:
    maxValue 
= 23;
    addZero 
= false;   
    
break;
   
case m:
    maxValue 
= 59;
    addZero 
= true;
    
break;
   
default:
  }

  
if(iValue > maxValue)
   iValue 
= 0;
  
if(iValue < 0)
   iValue 
= maxValue;
  
if(addZero){
   
if(iValue.toString().length == 1)
    iValue 
= "0" + iValue;
  }

  obj.text 
= iValue.toString();
  regainTimeObj();
 }

</script>
發佈了24 篇原創文章 · 獲贊 1 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章