用系统滚动条实现NumericUpDown的原理

    我们知道在Windows控件里有一个叫NumericUpDown的控件,使用这个控件后可以用鼠标点击或键盘上下键来微调数字,当然也可以直接输入。这是一个使用方便同时又能限制输入格式的很有用的控件,可惜在Web中却没有提供这个控件,我们只能面对几个土土的INPUT的衍生控件。

    不过也有很多人制作了NumericUpDown这个控件替代品,但是由于Web上同样没有提供ScrollBar这个控件,那些替代品一个通病就是模拟的用来微调那两个button始终不太和谐,而且显示的效果受网页字体的影响很大。最常用的就是用图片了,那样字体一大就完全对不上了,不是看图片不完整,就是看半个数字,真的是很恼火。

    有没有办法借用系统的滚动条来实现NumericUpDown控件中的微调button呢?这个确实比较的难,我们最容易想到的就是使用INPUT type="text"和Select把它们弄成一行高,然后就会出现和Windows的NumericUpDown控件十分相像的微调button。那正好啊,可是问题是这两个控件的滚动条的出现是一个系统的行为,而不是HTML元素的行为(不是指的behavior哦),我们没有办法去读取和设置这滚动条的属性,就象使用Select,我们甚至都做出了外观很professional的NUD控件了 ,可是却完全没有办法使用脚本读取和设置我们想要的数值

    既然不能响应系统滚动条的任何事件,那么我们就该从别的地方想办法了。使用viewport窗口里的onScroll事件来触发执行,因为只要滚动条有移动,onScroll就会触发,等于间接的俘获了系统滚动条上的点击事件,又因为可以通过onScroll的增量的正负来确定是Up按钮被点击了,还是Down按钮被点击了。那么使用这个特性来实现NumericUpDown控件似乎理所当然了?可是不幸还是有一些问题。

    假如我们使用div元素来做一个NumericUpDown控件,
0 11 1
。这个按钮已经很professinal了,而且不会受字体大小的任何影响。那么问题是什么呢?问题是当我们使用鼠标点击时按钮后,onScroll事件会被触发n(1-4)次@_@。当然使用鼠标滚轮或键盘上下键,也会触发n次onScroll事件。这个n到底可不可以度量呢?幸好是可以的,原来它是受字体大小影响的,当字体时Smallest时,n=1;字体时Smaller时,n=2;字体时Medium、Larger和Largest时,n=3或4。

    那么就算我们要使用onScroll也不能这么去判断n值呀,而且3或4的取值还不一定呢。后来又发现这些onScroll触发时的时间都是一样的,至少使用getTime()获得的毫秒值是相同的。用这个timestamp来判断也有还有问题,怎么都是问题啊,嗯,还真的都是问题。就是怎么去计数这几个timestamp相同的onScroll的问题。这个问题解决了,那么Web上的NumericUpDown控件就将会非常的professinal了

你可能感兴趣的:(滚动条)