最近自建Javascript库已日渐完善,在基础库的基础上,增加很多自制UI控件,除了之前展示的Grid,最近还完成了Tab,Accordion,Tree,DropDrag,DigitalNumber,以及矢量数字时钟等控件,本来想以文章的形式给大家分享这些控件代码,但是每个控件代码量都在200行以上,看来放上来是个不切合实际的事情。
今天主要想给大家分享的仅仅是Tab控件中的一个功能:如何实现可活动标题。这个功能的大致需求是,当Tab标题栏中 Tab页总宽度大于标题栏实际可见宽度后,超出的Tab页会被覆盖在标题栏的内层,同时两侧各增加一个半透明的Button,点击可使标题栏内部左右滑动。
Tab标题栏的Html组织结构如下:
Css结构不具体说明,只指明几个关键点:外层Div必须是 overflow:hidden;position:relative; 内层ul元素必须是 position:absolute;width:xxxxxpx。这里表示宽度足够长,这样当ul内部Tab页标题增多时,能形成一个内部遮挡的效果,两侧的 i 元素是左右滑动按钮。设置ul 的style.left即可控制它在外层div中的相对位置,设负值就向左侧移动,正值就往右侧移动。效果如下图:
![2011060800183941.jpg](https://i-blog.csdnimg.cn/blog_migrate/2db396ad36831967a1dea1d37110d9e2.jpeg)
下面就是javascript代码需要实现的逻辑,在每次增加新标题时,计算ul内元素总宽度,超过外层div宽度时,则生成两个dom元素,作为控制左右滑动的按钮,滑动效果使用了计时器函数,我的大致设计思路是这样的,为每个button注册一个"mousedown"事件,启动一个计时器,不断地改变ul的style.left数值。另外注册一个"mouseup"事件,关闭这个计时器听着移动。
计时器使用 setIterval,我采用了之前介绍的我类库中封装的 Function.createInterval 原型方法。代码如下:
var left = this .ul.offsetLeft,
style = this .ul.style;
if (left + 4 <= 0 ){
style.left = left + 4 + ' px ' ;
} else {
style.left = ' 0px ' ;
}
},
moveRight : function(){
var left = this .ul.offsetLeft,
style = this .ul.style;
if ( this .ulWidth + left - 4 >= this .ulcw - 20 ){
style.left = left - 4 + ' px ' ;
} else {
style.left = this .ulcw - this .ulWidth - 20 + ' px ' ;
}
},
HL.on(left, ' mousedown ' , function(){
movingTask = this .moveLeft.createInterval( 25 , this );
movingTask.run();
}, this );
HL.on(left, ' mouseup ' , function(){
movingTask.stop();
}, this );
HL.on(right, ' mousedown ' , function(){
movingTask = this .moveRight.createInterval( 25 , this );
movingTask.run();
}, this );
HL.on(right, ' mouseup ' , function(){
movingTask.stop();
}, this );
其中ulWidth 是ul内部元素总宽度,ulcw是外层div的可见宽度,这两个值会在每次触发 addtab 事件后缓存在原型变量中(Tab UI类也实现了 观察者模式接口),movingTask是一个闭包私有变量,控制滑动任务。
moveLeft 与 moveRight 函数作用是改变ul的left数值,并且对移动范围进行控制,具体逻辑你们看代码自己理解吧。
代码中还有很多前提条件没有写,关于标题左右滑动功能,这样基本可以实现,当然还要删除标题时,对坐标的一个恢复等等逻辑没有介绍,其实做UI还是蛮有意思的,实现各种各样复杂多变的动态效果,今天刚看了下《愤怒小鸟》的网页canvas版本,叹为观止,绝对今天开始强化学习下,OK今天先到这里