【鼠标拖动控制】
鼠标拖动控制,就是通过拖动滑块来设置定位。
这个就跟滚动条意思差不多,主要是通过_drag本身的拖放效果来实现的(详细看这里拖放效果)。
广州网站建设,网站建设,广州网页设计,广州网站设计
【鼠标点击控制】
鼠标点击控制,就是当点击容器的时候能定位到点击的位置。
一般来说只要把ClickCtrl鼠标点击控制程序绑定容器的click事件中就可以了。
但这里有个问题,滑块的点击(拖动控制)跟容器的点击会发生冲突,具体表现是拖放结束后就“顺便”触发了容器的click。
这个本来在滑块的点击事件中取消冒泡就可以:
- addEventHandler(this.Bar, "click", BindAsEventListener(this, function(e){ e.stopPropagation(); }));
但ie的click机制有点问题:
- <div style="width:100px; height:100px; background-color:#CCC;" onclick="alert(1)" >
- <div style=" height:50px; background-color:#C11;" onclick="event.stopPropagation?event.stopPropagation():(event.cancelBubble=true);" ></div>
- </div>
里面的div取消冒泡,点击它不会触发外面div的onclick,但如果在里面的div点,然拖动到外面的div放,就会触发了,而ff是不会的。
ps:从外面拖到里面也是一样的情况。
经过测试,我觉得是因为ie认为点击的点和放只要是发生在同一个元素的内部(包括内部的其他元素),那个这个点击就是有效的;而ff则认为点击的点和放必须在同一个元素内才有效(w3c标准应该也是这样)。
这个导致的问题是,当拖放结束时如果放开鼠标的地方是容器上,那么就会发生冲突了。
那对于ie的这个现象,解决方法其实也很多,我用的方法很简单,设一个属性_ondrag来表示是否拖放中。
具体就是在DragStart开始拖放滑动程序中把_ondrag设为true,并在DragStop结束拖放滑动程序中把它设为false:
- setTimeout(Bind(this, function(){ this._ondrag = false; }), 10);
这里用了setTimeout,因为拖放结束后才会触发容器的click,所以设一个延时,使这个值在容器的click触发后才修改。
这样就可以通过这个_ondrag来判断是否应该执行ClickCtrl了:
- addEventHandler(this.Container, "click", BindAsEventListener(this, function(e){ this._ondrag || this.ClickCtrl(e);}));
接着看ClickCtrl鼠标点击控制程序,首先获取容器的相对文档的位置:
- var o = this.Container, iLeft = o.offsetLeft, iTop = o.offsetTop;
- while (o.offsetParent) { o = o.offsetParent; iLeft += o.offsetLeft; iTop += o.offsetTop; }
注意,要逐级向上获取才能取得相对相对文档的位置。
然后通过pageX(pageY)和滑块(这里是要设置到滑块的中间位置所以取一半)得到要设置的位置:
- this.EasePos(e.pageX - iLeft - this.Bar.offsetWidth / 2, e.pageY - iTop - this.Bar.offsetHeight / 2);
这里要用pageX(pageY)来取值,而不是clientX(clientY),因为后者是没有计算滚动条的。
ps:ie没有pageX(pageY),不过在Event程序中已经给window.event添加了这个属性:
- oEvent.pageX = oEvent.clientX + document.documentElement.scrollLeft;
- oEvent.pageY = oEvent.clientY + document.documentElement.scrollTop;
【鼠标滚轮控制】
鼠标滚轮控制,就是通过鼠标滚轮滚动来控制滑块的滑动。
首先ie绑定滚轮事件用的是mousewheel,ff用的是DOMMouseScroll,所以在WheelBind绑定鼠标滚轮程序中是这样设置的:
- addEventHandler(o, isIE ? "mousewheel" : "DOMMouseScroll", BindAsEventListener(this, this.WheelCtrl));
接着看WheelCtrl鼠标滚轮控制程序,通过event的detail属性可以获取鼠标滚动的距离(值大小)和方向(正负)。
利用它来设置要滑动的位置:
- var i = this.WheelSpeed * e.detail;
- this.SetPos(this.Bar.offsetLeft + i, this.Bar.offsetTop + i);
但ie没有detail,对应的有wheelDelta,wheelDelta的数值刚好是detail的40倍,而且方向相反(正负相反),所以Event程序中是这样给window.event添加detail的:
- oEvent.detail = oEvent.wheelDelta / (-40);
为了防止触发其他滚动条,这里用了preventDefault取消默认动作。
注意不是用取消冒泡(貌似滚屏是事件的默认动作)。
广州网站建设,网站建设,广州网页设计,广州网站设计
【方向键控制】
方向键控制,就是通过键盘的左右(上下)方向键来控制滑块的滑动。
首先用KeyBind方向键绑定程序把KeyCtrl方向键控制程序绑定到对象的keydown事件中:
- addEventHandler(o, "keydown", BindAsEventListener(this, this.KeyCtrl));
在KeyCtrl中,通过event的keyCode属性获取键盘的按键(左37、上38、右39、下40)并进行相应的操作:
- switch (e.keyCode) {
- case 37 ://左
- iLeft -= iWidth; break;
- case 38 ://上
- iTop -= iHeight; break;
- case 39 ://右
- iLeft += iWidth; break;
- case 40 ://下
- iTop += iHeight; break;
- default :
- return;//不是方向按键返回
- }
同样为了防止触发其他滚动条,也用了preventDefault取消默认动作。



