【位置狀態(tài)】
程序中有位置程序onMin(最小值時(shí))、onMax(最大值時(shí))和onMid(中間值時(shí))分別在各自位置時(shí)執(zhí)行。 ps:onMid指的是除最小值最大值外的中間部分,不是中心值。 程序是在Move滑動(dòng)程序中通過百分比來判斷當(dāng)前位置的(0時(shí)為最小值,1時(shí)為最大值,其他為中間值)。 由于Move程序并不會(huì)因?yàn)榈搅藰O限值就停止,如果僅僅根據(jù)百分比來判斷那么到了極限值,值雖然不變但程序就會(huì)一直被觸發(fā)。 而我需要的是當(dāng)值不變的時(shí)候,對(duì)應(yīng)位置程序僅僅觸發(fā)一次。根據(jù)需求就衍生出三個(gè)位置狀態(tài)屬性_IsMin(最小值狀態(tài))、_IsMax(最大值狀態(tài))和_IsMid(中間值狀態(tài))。 用這幾個(gè)狀態(tài)屬性和百分比就能實(shí)現(xiàn)需要的效果了:
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; }
這三個(gè)位置狀態(tài)屬性在其他程序中也用來判斷是否到了極限值。
【鼠標(biāo)拖動(dòng)控制】
鼠標(biāo)拖動(dòng)控制,就是通過拖動(dòng)滑塊來設(shè)置定位。 這個(gè)就跟滾動(dòng)條意思差不多,主要是通過_drag本身的拖放效果來實(shí)現(xiàn)的(詳細(xì)看這里拖放效果)。
【鼠標(biāo)點(diǎn)擊控制】
鼠標(biāo)點(diǎn)擊控制,就是當(dāng)點(diǎn)擊容器的時(shí)候能定位到點(diǎn)擊的位置。 一般來說只要把ClickCtrl鼠標(biāo)點(diǎn)擊控制程序綁定容器的click事件中就可以了。 但這里有個(gè)問題,滑塊的點(diǎn)擊(拖動(dòng)控制)跟容器的點(diǎn)擊會(huì)發(fā)生沖突,具體表現(xiàn)是拖放結(jié)束后就“順便”觸發(fā)了容器的click。 這個(gè)本來在滑塊的點(diǎn)擊事件中取消冒泡就可以:
addEventHandler(this.Bar, "click", BindAsEventListener(this, function(e){ e.stopPropagation(); }));
但ie的click機(jī)制有點(diǎn)問題,測(cè)試下面的點(diǎn)擊:
運(yùn)行代碼框
[Ctrl+A 全部選擇 提示:你可先修改部分代碼,再按運(yùn)行]
里面的div取消冒泡,點(diǎn)擊它不會(huì)觸發(fā)外面div的onclick,但如果在里面的div點(diǎn),然拖動(dòng)到外面的div放,就會(huì)觸發(fā)了,而ff是不會(huì)的。 ps:從外面拖到里面也是一樣的情況。 經(jīng)過測(cè)試,我覺得是因?yàn)閕e認(rèn)為點(diǎn)擊的點(diǎn)和放只要是發(fā)生在同一個(gè)元素的內(nèi)部(包括內(nèi)部的其他元素),那個(gè)這個(gè)點(diǎn)擊就是有效的;而ff則認(rèn)為點(diǎn)擊的點(diǎn)和放必須在同一個(gè)元素內(nèi)才有效(w3c標(biāo)準(zhǔn)應(yīng)該也是這樣)。 這個(gè)導(dǎo)致的問題是,當(dāng)拖放結(jié)束時(shí)如果放開鼠標(biāo)的地方是容器上,那么就會(huì)發(fā)生沖突了。
那對(duì)于ie的這個(gè)現(xiàn)象,解決方法其實(shí)也很多,我用的方法很簡(jiǎn)單,設(shè)一個(gè)屬性_ondrag來表示是否拖放中。 具體就是在DragStart開始拖放滑動(dòng)程序中把_ondrag設(shè)為true,并在DragStop結(jié)束拖放滑動(dòng)程序中把它設(shè)為false:
setTimeout(Bind(this, function(){ this._ondrag = false; }), 10);
這里用了setTimeout,因?yàn)橥戏沤Y(jié)束后才會(huì)觸發(fā)容器的click,所以設(shè)一個(gè)延時(shí),使這個(gè)值在容器的click觸發(fā)后才修改。 這樣就可以通過這個(gè)_ondrag來判斷是否應(yīng)該執(zhí)行ClickCtrl了:
addEventHandler(this.Container, "click", BindAsEventListener(this, function(e){ this._ondrag || this.ClickCtrl(e);}));
接著看ClickCtrl鼠標(biāo)點(diǎn)擊控制程序,首先獲取容器的相對(duì)文檔的位置:
var o = this.Container, iLeft = o.offsetLeft, iTop = o.offsetTop; while (o.offsetParent) { o = o.offsetParent; iLeft += o.offsetLeft; iTop += o.offsetTop; }
注意,要逐級(jí)向上獲取才能取得相對(duì)相對(duì)文檔的位置。 然后通過pageX(pageY)和滑塊(這里是要設(shè)置到滑塊的中間位置所以取一半)得到要設(shè)置的位置:
this.EasePos(e.pageX - iLeft - this.Bar.offsetWidth / 2, e.pageY - iTop - this.Bar.offsetHeight / 2);
這里要用pageX(pageY)來取值,而不是clientX(clientY),因?yàn)楹笳呤菦]有計(jì)算滾動(dòng)條的。 ps:ie沒有pageX(pageY),不過在Event程序中已經(jīng)給window.event添加了這個(gè)屬性:
oEvent.pageX = oEvent.clientX + document.documentElement.scrollLeft; oEvent.pageY = oEvent.clientY + document.documentElement.scrollTop;
出處:藍(lán)色理想
責(zé)任編輯:bluehearts
上一頁(yè) 仿Apple滑動(dòng)條(拖動(dòng))產(chǎn)品展示效果 [2] 下一頁(yè) 仿Apple滑動(dòng)條(拖動(dòng))產(chǎn)品展示效果 [4]
◎進(jìn)入論壇網(wǎng)頁(yè)制作、WEB標(biāo)準(zhǔn)化版塊參加討論,我還想發(fā)表評(píng)論。
|