昨天研究了一下系統滾動條,準備使用它來實現一個NumericUpDown控件,因為它可以帶來最正宗的微調按鈕外觀
,并說了一下可以使用viewport里的onScroll事件來獲取系統滾動條的上下點擊動作。
??? 同時昨天還說了onScroll事件的一個問題是,在點擊了滾動條的上下按鈕后,onScroll事件會被連續的觸發n次(n取[1,4])。我們發現這些連續事件都在一個很小的timespan里觸發的,也就在12ms以內。于是我們在onScroll事件中使用setTimeout來啟動一次有意義的數值變化,代碼如下,分支false用來判斷點擊的方向。
if?(?NumericUpDown.ScrollBegin?==?0?)

{??

????NumericUpDown.ScrollBegin?=?
new?Date().getTime();

????NumericUpDown.ChangeNumeric.Element?=?elmt;

????window.setTimeout(NumericUpDown.ChangeNumeric,?12);

}
else
{

????
var?time?=?
new?Date().getTime();

????
if?(?NumericUpDown.ScrollDirection?==?0?)

????{

?????????
var?scrollOffset?=?NumericUpDown.ScrollTopValue?-?elmt.scrollTop;

?????????NumericUpDown.ScrollDirection?=?scrollOffset?>?0???1?:?-1;?

?????????NumericUpDown.ScrollTopValue?=?elmt.scrollTop;?

????}

}
??? 控件使用一個DIV,一個SPAN和一個INPUT type='hidden'來實現,DIV的overflow-y設為scroll,SPAN用來顯示當前的數值,INPUT type='hidden'用來存放控件當前的數值。
???
初始化控件的時候,再動態添加兩個SPAN分別到默認SPAN的兩端,這是因為滾動條如果處在任何一個頂端(top或bottom)是不會觸發onScroll事件的,也就是說要把默認那個SPAN放到DIV的正中間,前后在分別有一個SPAN。 
?elmt.Current?=?elmt.Input.value;

?
var?current?=?parseInt(elmt.Current);

?
var?step?=?parseInt(elmt.Step);

?
var?previousSpan?=?NumericUpDown.CreateSpan();

?previousSpan.innerText?=?current?-?step;

?
var?nextSpan?=?NumericUpDown.CreateSpan();

?nextSpan.innerText?=?current?+?step;

?
var?currentSpan?=?elmt.all.tags('SPAN')[0];

?currentSpan.insertAdjacentElement('beforeBegin',?previousSpan);

?currentSpan.insertAdjacentElement('afterEnd',?nextSpan);

?NumericUpDown.ScrollTo.CurrentSpan?=?currentSpan;

?window.setTimeout(NumericUpDown.ScrollTo,?1);????????

?elmt.IsInitialized?=?
true;
????
????
控件NumericUpDown代碼為:? 
<
script?language="javascript">
script>
????
??? 由于在這個頁面上注入代碼太麻煩了,就把demo放到這里了。雖然這個NumericUpDown自然的就可以支持鍵盤Up & Down和PageUp & PageDown,可是最后一個問題卻真的沒有招了,以至于我最終只能放棄這個嘗試了。看看demo,框里的數字有些抖動是吧?這是系統的默認行為,而且點擊的越快,抖的也越快,真的沒有辦法了

。
??? 所以完成了也只能叫做Unusable版...
? 本文轉自博客園鳥食軒的博客,原文鏈接:http://www.cnblogs.com/birdshome/,如需轉載請自行聯系原博主。