一区二区久久-一区二区三区www-一区二区三区久久-一区二区三区久久精品-麻豆国产一区二区在线观看-麻豆国产视频

JavaScript 浮動定位提示效果實現代碼第1/2頁

這個效果本身難度不大,主要在程序結構和擴展中下了些功夫,務求用起來更方便,能用在更多的地方。
程序特點
1,同一個提示框用在多個觸發元素時,只需一個實例;
2,顯示和隱藏分別有點擊方式和觸發方式選擇;
3,能設置延時顯示和隱藏;
4,有25種預設定位位置;
5,可在預設定位基礎上,再自定義定位;
6,可設置自適應窗口定位;
程序說明
【Tip對象】
Tip對象就是用來顯示提示信息的容器,程序用Tip屬性表示。這個沒什么要求,程序初始化時會對它進行一些設置。
首先進行下面設置:
復制代碼 代碼如下:
var css = this._cssTip;
css.margin = 0;
css.position = "absolute"; css.visibility = "hidden";
css.display = "block"; css.zIndex = 99;
css.left = this._cssTip.top = "-9999px";

其中margin設為0是為了避免一些定位問題,用visibility來隱藏而不是display是因為程序需要獲取Tip的offsetWidth、offsetHeight,還需要設置left和top是避免因Tip占位出現的滾動條。
因為Tip可能會在其他定位元素里面,所以還要設兩個offset修正參數:
復制代碼 代碼如下:
var iLeft = 0, iTop = 0, p = this.Tip;
while (p.offsetParent) {
p = p.offsetParent; iLeft += p.offsetLeft; iTop += p.offsetTop;
};
this._offsetleft = iLeft;
this._offsettop = iTop;

最后給Tip的mouseover加一個事件,具體后面再說明。
【觸發對象】
由于很多情況下都是一個Tip對應多個地方的提示,所以程序參考了Table排序的方式,添加了一個Add方法。
一個Tip實例化后,再用Add方法就可以對多個觸發元素分別添加觸發對象,程序中用_trigger屬性表示當前的觸發對象。
Add方法的一個必要參數是觸發元素,就是觸發顯示Tip的元素。
需要的話還可以用options參數,來自定義觸發對象的屬性,包括:
屬性: 默認值//說明
復制代碼 代碼如下:
ShowType: "both",//顯示方式
HideType: "both",//隱藏方式
ShowDelayType: "touch",//顯示延遲方式
HideDelayType: "touch",//隱藏延遲方式
ShowDelay: 300,//顯示延時時間
HideDelay: 300,//隱藏延時時間
Fixed: {},//定位對象
onShow: function(){},//顯示時執行
onHide: function(){}//隱藏時執行

具體作用后面再說明,可以在程序初始化時修改這些默認值。
一個經典應用是在onShow中把Tip修改為各個觸發對象對應的內容。
此外還有Elem屬性保存觸發元素。
【顯示和隱藏】
提示效果的一個重點就是顯示和隱藏提示信息。程序是通過設置Tip的visibility是否hidden來顯示和隱藏Tip的。
具體的顯示和隱藏程序分別在Show和Hide程序中,還有ReadyShow和ReadyHide程序,主要用來處理延時。
這種提示效果的一個特點是鼠標移動到Tip上時,會保持顯示狀態。
為了實現這個效果,給Tip的mouseover寫入程序:
this.Check(e.relatedTarget) && clearTimeout(this._timer);
其中Check程序是用來判斷relatedTarget是不外部元素,即鼠標離開的元素是不是外部元素。
如果是外部元素,就說明當前是隱藏延時階段,那么只要清除定時器來取消隱藏就可以了。
這里的外部元素是指觸發元素和Tip對象本身及其內部元素以外的元素。
這個有點拗口,那再看看Check程序是怎么判斷的就明白了:
復制代碼 代碼如下:
return !this._trigger ||
!(
this.Tip === elem || this._trigger.Elem === elem ||
Contains(this.Tip, elem) || Contains(this._trigger.Elem, elem)
);

首先判斷_trigger是否存在,不存在的話說明是剛開始觸發,也看成是外部觸發。
存在的話再判斷傳遞過來的元素是不是Tip或觸發元素本身,最后再用Contains判斷判斷是不是在Tip或觸發元素內部。
ps:關于Contains請參考這里的比較文檔位置。
這樣得到的是判斷是否內部元素,最后取反就是判斷是否外部元素了。
【點擊方式】
點擊方式顯示是指點擊觸發元素的時候顯示Tip。
在Add程序中會給觸發元素的click事件綁定以下程序:
復制代碼 代碼如下:
addEvent(elem, "click", BindAsEventListener(this, function(e){
if ( this.IsClick(trigger.ShowType) ) {
if ( this.CheckShow(trigger) ) {
this.ReadyShow(this.IsClick(trigger.ShowDelayType));
} else {
clearTimeout(this._timer);
};
};
}));

首先根據ClickShow判斷是否進行點擊顯示,再用CheckShow檢測是否同一個觸發對象。
CheckShow程序是這樣的:
復制代碼 代碼如下:
if (trigger !== this._trigger) {
this.Hide(); this._trigger = trigger; return true;
} else { return false; };

如果不是同一個觸發對象,就先執行Hide清理前一個觸發對象,防止沖突,再執行ReadyShow來顯示。
如果是同一個觸發對象,就說明當前是延時隱藏階段,清除定時器保持顯示狀態就行了。
對應的,點擊方式隱藏是指點擊外部元素的時候隱藏Tip。
在ReadyShow里,當使用點擊方式隱藏時,就會把_fCH綁定到document的click事件里:
this.IsTouch(trigger.HideType) && addEvent(this._trigger.Elem, "mouseout", this._fTH);
注意這里要把隱藏綁定事件放到ReadyShow,而不是Show里面,因為延時的時候有可能還沒有顯示就觸發了隱藏事件。
其中_fCH是在初始化時定義的一個屬性,用于添加和移除點擊隱藏事件:
復制代碼 代碼如下:
this._fCH = BindAsEventListener(this, function(e) {
if (this.Check(e.target) && this.CheckHide()) {
this.ReadyHide(this.IsClick(this._trigger.HideDelayType));
};
});

注意不同于點擊顯示,由于綁定的是document,隱藏前要先確定e.target是不是外部元素。
其中CheckHide是作用是檢查Tip當前是不是隱藏狀態:
復制代碼 代碼如下:
if (this._cssTip.visibility === "hidden") {
clearTimeout(this._timer);
removeEvent(this._trigger.Elem, "mouseout", this._fTH);
this._trigger = null;
removeEvent(document, "click", this._fCH);
return false;
} else { return true; };

如果本來就是隱藏狀態,清除定時器移除事件就行,不需要再執行Hide了。
【觸發方式】
觸發方式針對的是mouseover和mouseout,它的流程跟點擊方式是差不多的。
觸發方式顯示是指鼠標從外部元素進入觸發元素(觸發mouseover)的時候顯示Tip。
在Add程序中會給觸發元素的mouseover事件綁定以下程序:
復制代碼 代碼如下:
addEvent(elem, "mouseover", BindAsEventListener(this, function(e){
if ( this.IsTouch(trigger.ShowType) ) {
if (this.CheckShow(trigger)) {
this.ReadyShow(this.IsTouch(trigger.ShowDelayType));
} else if (this.Check(e.relatedTarget)) {
clearTimeout(this._timer);
};
};
}));

跟點擊方式類似,也需要執行一次CheckShow,但不同的是,還會用Check判斷e.relatedTarget是不是外部對象。
這是因為mouseover可能是從觸發元素的內部元素(包括Tip)進入或內部元素冒泡觸發的,而這些情況不需要任何操作。
對應的,觸發方式隱藏是指鼠標從觸發元素或Tip離開時隱藏Tip。
當TouchHide為true時,在ReadyShow的時候會把_fTH綁定到觸發元素的mouseout事件里:
this.IsTouch(trigger.HideType) && addEvent(this._trigger.Elem, "mouseout", this._fTH);
在Show的時候,再綁定到Tip的mouseout:
this.IsClick(trigger.HideType) && addEvent(document, "click", this._fCH);
在ReadyShow綁定的原因同上,而Tip只需顯示時綁定。
其中_fTH跟_fCH類似,也是在初始化時定義的一個屬性,用于添加和移除觸發隱藏事件:
復制代碼 代碼如下:
this._fTH = BindAsEventListener(this, function(e) {
if (this.Check(e.relatedTarget) && this.CheckHide()) {
this.ReadyHide(this.IsTouch(this._trigger.HideDelayType));
};
});

不同的是mouseout在Check的時候是用e.relatedTarget。
【觸發原理】
上面是從程序的角度說明了觸發顯示和隱藏的過程,但要真正理解的話還需要做一次細致的分析。
下面是以觸發方式的顯示隱藏為例做的流程圖:

下面是文字說明:
1,等待觸發顯示;
2,進入觸發元素,如果設置延時,跳到3,如果沒有設置延時,跳到4;
3,延時時間內,離開到外部元素,清除定時器,返回1,超過延時時間,跳到4;
4,執行顯示程序;
5,顯示Tip狀態;
6,離開觸發元素,如果是進入到Tip,跳到7,如果是離開到外部元素,跳到9;
7,保持顯示狀態;
8,離開Tip,如果是進入觸發元素,返回5,如果是離開到外部元素,跳到9;
9,如果設置延時,跳到10,如果沒有設置延時,跳到11;
10,延時時間內,如果進入Tip,清除定時器,返回7,如果進入觸發元素,清除定時器,返回5,超過延時時間,跳到11;
11,執行隱藏程序,返回1;

再對照程序,應該就能理解整個流程了,當然可能還不是那么好理解。
這個流程也只是單例的情況,多例的時候還要多加一些判斷。
可以說這個流程看似不難,但如果想做一個最優化的流程,那要考慮的細節地方可能會讓人受不了。
點擊方式跟觸發方式的流程是差不多的,而且更簡單,這里就不重復了。


【元素定位】

完成了顯示隱藏,就到本程序另一個重點,元素定位。
程序使用一個GetRelative函數,通過定位元素、參考元素和參數對象來獲取形如{ Left: 100, Top: 200 }的定位參數結果。
計算結果結合了以下定位方式:預設定位,自定義定位,自適應定位。
觸發對象的Fixed屬性就是用來保存定位參數對象的,包括一下屬性:
屬性: 默認值//說明
Align: "clientleft",//水平方向定位
vAlign: "clienttop",//垂直方向定位
CustomLeft: 0,//自定義left定位
CustomTop: 0,//自定義top定位
PercentLeft: 0,//自定義left百分比定位
PercentTop: 0,//自定義top百分比定位
Adaptive: false,//是否自適應定位
Reset: false//自適應定位時是否重新定位
下面再看看如何通過這些屬性設置定位。


【預設定位和自定義定位】

預設定位的意思是使用程序25個預設位置來定位。
25個位置是怎么來的呢?看下面的具體演示:

JavaScript技術JavaScript 浮動定位提示效果實現代碼第1/2頁,轉載需保留來源!

鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。

主站蜘蛛池模板: 午夜免费的国产片在线观看 | 国产91激情对白露脸全程 | 男女性色大片免费网站 | 亚洲国产爱 | 一道精品视频一区二区三区图片 | 一区二区在线视频观看 | 国产亚洲精品一品区99热 | 国产极品一区 | 玖玖香蕉视频 | 久久五月天婷婷 | 99国产成人高清在线视频 | 亚洲综合在线成人一区 | 欧美成人v视频免费看 | 午夜激情福利 | 美女一级免费毛片 | 久久久香蕉 | 亚洲国产成人久久 | 免看一级a毛片一片成人不卡 | 97精品久久天干天天蜜 | 精品福利在线观看 | 亚洲成人贴图 | 日本加勒比一区 | 国产成人+亚洲欧洲 | 欧美特黄a级高清免费大片 欧美特黄a级高清免费看片 | 国产亚洲一区呦系列 | 一区二区三区高清在线观看 | 99精品视频一区在线视频免费观看 | 亚洲色四在线视频观看 | 另类视频色综合 | 黄色网址在线播放 | 日本乱人伦在线观看免费 | 伊人小婷婷色香综合缴缴情 | 日韩久久久精品首页 | 男女男精品视频免费观看 | 色婷婷视频在线 | 精品国产第一国产综合精品 | 91精品久久久久久久久中文字幕 | 一道精品视频一区二区三区男同 | 精品国产一区二区三区四 | 2019天天操天天干天天透 | 久久久精品影院 |