仿Apple滑动条产品展示效果(3)

http://www.itjxue.com  2015-08-06 23:18  来源:未知  点击次数: 

【位置状态】

程序中有位置程序onMin(最小值时)、onMax(最大值时)和onMid(中间值时)分别在各自位置时执行。
ps:onMid指的是除最小值最大值外的中间部分,不是中心值。
程序是在Move滑动程序中通过百分比来判断当前位置的(0时为最小值,1时为最大值,其他为中间值)。
由于Move程序并不会因为到了极限值就停止,如果仅仅根据百分比来判断那么到了极限值,值虽然不变但程序就会一直被触发。
而我需要的是当值不变的时候,对应位置程序仅仅触发一次。根据需求就衍生出三个位置状态属性_IsMin(最小值状态)、_IsMax(最大值状态)和_IsMid(中间值状态)。
用这几个状态属性和百分比就能实现需要的效果了:

var percent = this.GetPercent();
//最小值判断
if(percent > 0){
    this._IsMin = false;
}else{
    if(!this._IsMin){ this.onMin(); this._IsMin = true; }
}
//最大值判断
if(percent < 1){
    this._IsMax = false;
}else{
    if(!this._IsMax){ this.onMax(); this._IsMax = true; }
}
//中间值判断
if(percent > 0 && percent < 1){
    if(!this._IsMid){ this.onMid(); this._IsMid = true; }
}else{
    this._IsMid = false;
}

这三个位置状态属性在其他程序中也用来判断是否到了极限值。

【鼠标拖动控制】

鼠标拖动控制,就是通过拖动滑块来设置定位。
这个就跟滚动条意思差不多,主要是通过_drag本身的拖放效果来实现的(详细看这里拖放效果)。

【鼠标点击控制】

鼠标点击控制,就是当点击容器的时候能定位到点击的位置。
一般来说只要把ClickCtrl鼠标点击控制程序绑定容器的click事件中就可以了。
但这里有个问题,滑块的点击(拖动控制)跟容器的点击会发生冲突,具体表现是拖放结束后就“顺便”触发了容器的click。
这个本来在滑块的点击事件中取消冒泡就可以:

addEventHandler(this.Bar, "click", BindAsEventListener(this, function(e){ e.stopPropagation(); }));

但ie的click机制有点问题,测试下面的点击:

运行代码框

[Ctrl+A 全部选择 提示:你可先修改部分代码,再按运行]

里面的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;

(责任编辑:IT教学网)

更多

推荐Javascript/Ajax文章