天天看點

AlertBox 彈出層(資訊提示框)效果

彈出層就是相對文檔或視窗定位的一個層,一般用來顯示提示資訊、廣告等内容,還可以配合覆寫層來鎖定頁面。

在[url=http://www.cnblogs.com/cloudgamer/archive/2008/09/15/1290954.html]仿Lightbox效果[/url]中,已經基本實作了這個效果,這次主要改進了ie6在fixed時的抖動問題。

此外,還增加了一個用來相容ie6的fixed的方法,覆寫層也重新“包裝”,程式也改成元件的結構。

相容:ie6/7/8, firefox 3.6.8, opera 10.6, safari 5.0.1, chrome 5.0

[img]http://dl.iteye.com/upload/attachment/329659/6525993e-dc7f-3fb9-90c0-0245020b291a.jpg[/img]

[url=http://www.cnblogs.com/cloudgamer/archive/2010/10/11/AlertBox.html][b]前台效果預覽[/b][/url]

[url=http://dl.iteye.com/topics/download/5ef49027-39c2-348c-b2d5-fa2488e2277c][b]完整執行個體下載下傳[/b][/url]

[b]程式說明[/b]

[b]【實作原理】[/b]

彈出層的基本原理在[url=http://www.cnblogs.com/cloudgamer/archive/2008/09/15/1290954.html]仿Lightbox效果[/url]中已經說的差不多了。

關鍵的地方就是定位,一般相對文檔的定位用absolute就行了。

要随屏移動,即相對視窗定位,就用fixed定位。

這些實作起來都很簡單,除了不支援fixed的ie6。

[b]【相容ie6的fixed】[/b]

由于ie6本身不支援fixed定位,隻能模拟或取巧來間接實作。

最原始的方法是在window的scroll事件中不斷修正彈出層的位置,像[url=http://www.cnblogs.com/cloudgamer/archive/2008/09/15/1290954.html]仿Lightbox效果[/url]那樣。

後來有人發現還可以[url=http://bbs.blueidea.com/thread-2938030-1-1.html]通過reflow“離奇”地實作[/url]。

但以上方法都有一個缺陷,滾動時彈出層會“發抖”,很不舒服(可以用緩動等來改善)。

想要不發抖,可以通過html和css的巧妙應用來實作,具體參考[url=http://bbs.blueidea.com/thread-2930592-1-1.html]14px的介紹[/url]。

原理是用一個容器代替body,然後對不會動的body絕對定位。

看來很完美,但有一個緻命的問題,這個方法需要修改html結構,會影響到相關的一些東西,例如window的scroll事件等。

程式中用了另一個方法,通過body的背景和expression來實作,下面是一個相容的fixed效果:

[code]<!DOCTYPE html>

<html>

<head>

<style>

body {

_background: url(about:blank) fixed;

}

.fixable {

position:fixed;

top:100px;

_position:absolute;

_top:expression((document).documentElement.scrollTop+100);

}

</style>

</head>

<body style="height:1500px;">

<div class="fixable">fixable</div>

</body>

</html>[/code]

以上代碼能相容ie6實作fixed,比較關鍵的是:

body的background-attachment必須是fixed;

把要fixed的元素設定絕對定位,并且用expression不斷修正top/left。

具體原理我也不清楚,可能是body背景在fixed之後,會優先重繪expression的結果。

ps:expression裡面必須用eval或加括号,才能不斷觸發運算(具體原因不明)。

關于這個方法的介紹可以看[url=http://www.gunlaug.no/contents/wd_additions_15.html]position: fixed in IE/win[/url]和[url=http://www.qianduan.net/fix-ie6-dont-support-position-fixed-bug.html]修正IE6不支援position:fixed的bug[/url]等。

相比前面的方法,這個是比較完美的了,但也有一些問題,例如body的背景隻能用fixed,使用expression資源消耗相對較大。

更大的問題是不能實作用百分比值或right/bottom來定位。

為了解決這個問題,程式使用了一個定位層,這個層用上面的方法實作fixed定位,尺寸跟視窗大小一樣,并且位置重合,那麼隻要用一般的定位方法相對這個層定位,就能達到相對視窗定位的效果了。

相容程式主要在RepairFixed對象中,首先設定body背景:

[code]if (body.currentStyle.backgroundAttachment !== "fixed") {

if (body.currentStyle.backgroundImage === "none") {

body.runtimeStyle.backgroundRepeat = "no-repeat";

body.runtimeStyle.backgroundImage = "url(about:blank)";

}

body.runtimeStyle.backgroundAttachment = "fixed";

}[/code]

參考自DE的[url=http://code.google.com/p/ie7-js/]IE7.js[/url],用"url(about:blank)"就不需要另外加圖檔。

再建立定位層:

[code]layer = document.createElement("<div style='position:absolute;border:0;padding:0;margin:0;overflow:hidden;background:transparent;top:expression((document).documentElement.scrollTop);left:expression((document).documentElement.scrollLeft);width:expression((document).documentElement.clientWidth);height:expression((document).documentElement.clientHeight);display:block;'>");[/code]

由于視窗大小可能會改變,除了top/left外,width/height也需要用expression修正。

定位層還要設定"overflow:hidden",好處是不會因彈出層在document原來的範圍外而自動擴大document。

ie6測試以下代碼,document會随着下滾而不斷擴大:

[code]<!DOCTYPE html>

<html>

<head>

<style>

body {

_background: url(about:blank) fixed;

}

.fixable {

position:absolute;

top:expression((document).documentElement.scrollTop+(document).documentElement.clientHeight);

}

</style>

</head>

<body>

<div class="fixable">fixable</div>

</body>

</html>[/code]

加上"overflow:hidden"就可以防止這種情況。

然後彈出層通過append方法修改為"absolute"定位,并插入到這個定位層,這樣就能實作fixed效果了。

由于這個定位層比較耗資源,是以在有元素插入時才會插到body中。

在不需要fixed的時候,要用remove方法從定位層中移除,當定位層内沒有需要定位元素就會自動從body移除。

ps:隐藏的話expression還會繼續執行,要移出文檔才行。

[b]【居中效果】[/b]

加入居中擴充程式,并且設定center為true,就會自動相對視窗居中。

居中的原理跟仿Lightbox效果是一樣的,通過設定負的元素尺寸一半的margin和"50%"的top/left來居中。

要注意的是不是使用fixed定位時,計算需要加上scrollTop/scrollLeft。

[b]【覆寫層】[/b]

在仿Lightbox效果中,ie6的覆寫層是通過建立一個覆寫整個頁面的層來做的。

使用新的相容fixed方法後,就不用另外做相容,按照fixed的效果做就行了。

覆寫層是由AlertBox擴充而來,它其實就是一個大小跟視窗一樣,并且跟視窗重合的彈出層。

由于覆寫層一般隻需要定義一個就行了,這裡把它做成一個OverLay對象,使用時直接調用它的show和close方法。

[b]【遮蓋select】[/b]

在仿Lightbox效果中介紹過兩種遮蓋select的方法:隐藏和iframe。

程式是通過iframe來遮蓋的,放在ie6的相容擴充程式中。

在iframe定位時要注意,要定位到彈出層的負的clientTop/clientLeft,這樣才能保證邊框不會被遮住。

[b]使用技巧[/b]

[b]【定位】[/b]

除了居中,程式會按照彈出層本身的定位樣式來顯示。

不是fixed定位時要注意,在ie6是相對目前視窗來定位的,其他都是相對第一屏視窗來定位的。

還要注意,必須聲明DOCTYPE,才能正确定位。

程式為了盡量通用,降低了效率(用了4個expression),是以最好還是根據實際情況自己來調整。

ps:需要像[url=http://www.cnblogs.com/cloudgamer/archive/2009/07/07/FixedTips.html]定位提示效果[/url]那樣預設定位的話,可以自行擴充。

[b]【鎖定鍵盤】[/b]

使用覆寫層時,為了防止使用者通過鍵盤操作頁面,可以在document的keydown中執行preventDefault來禁用。

如果彈出層需要正常操作,隻要在彈出層的keydown中執行stopPropagation就行了。

[b]【拖動彈窗】[/b]

這裡隻是簡單的加上拖動功能,要注意的是fixed定位時,計算拖動的參考對象是不同的。

更詳細的拖動介紹可以看看這個[url=http://www.cnblogs.com/cloudgamer/archive/2008/11/17/Drag.html]拖動效果[/url]。

[b]使用說明[/b]

執行個體化時,必須有彈出層作為參數:

[code]new AlertBox("idBox");[/code]

可選參數用來設定程式的預設屬性,包括:

屬性: 預設值//說明

fixed: false,//是否固定定位

zIndex: 1000,//層疊數

onShow: $$.emptyFunction,//顯示時執行

onClose: $$.emptyFunction//關閉時執行

還提供了以下方法:

show:顯示彈出層;

close:隐藏彈出層;

dispose:銷毀程式。

加入相容ie6擴充程式後,會自動修正ie6的fixed問題,可根據fixSelect屬性設定是否修正select遮蓋bug,預設是。

加入居中擴充程式後,可根據center屬性設定是否居中,預設否。

RepairFixed修正fixed對象,可獨立使用,有append和remove方法添加和移除需要fixed的元素,隻能在ie6使用。

OverLay覆寫層對象,有如下屬性:

屬性: 預設值//說明

"color": "#fff",//背景色

"opacity": .5,//透明度(0-1)

"zIndex": 100,//層疊值

還有show和close方法顯示和隐藏覆寫層。

繼續閱讀