Popup

 

Web的桌面提醒:Popup一,什麼是Popup 

在IE5.
5+中開始支持的Popup窗口有很多很特別的特性: 

Popup窗口可以超出瀏覽器窗口區域; 
可以不用擔心被下拉框、flash、Iframe等這些東西遮擋; 
即時窗口沒有焦點,Popup窗口也可以彈出並顯示 
一個Popup窗口打開後,當在它的區域以外點擊或者另一個Popup窗口被打開時都會自動關閉; 
Popup窗口是沒有焦點的; 
用戶不能改變Popup窗口大小; 
Popup窗口中的內容是不能被選擇的; 
...... 
只是Web下的Popup比起Windows中的Popup還是弱一些,但是已經夠用了。Msdn上對Popup有非常詳細的介紹“Using the Popup Object (Internet Explorer 
- DHTML) ” 

二,怎麼創建一個Popup 

Msdn上的示例代碼: 
// 創建Popup對象var oPopup = window.createPopup();// Popup對象和Window對象一樣,裏面包含了一個完整的HTML文檔var oPopupBody = oPopup.document.body;// 在Body中插入HTMLoPopupBody.innerHTML = "Display some <B>HTML</B> here.";// 設置顯示的位置、大小、參照物oPopup.show(100, 100, 200, 50, document.body); 
三,Popup的顯示 

多個Popup不能共存(Popup中創建Popup除外),所以web中的Popup不方便像Msn Messenger的Popup提示那樣“爬樓梯”,所以最簡單有效的方法就是像Outlook2003的Popup一樣,逐個Popup提醒。 
(參考WebMessenger的實現)用Js建個隊列,將需要Popup提示的內容都放在隊列中,用一個定時器,定時從隊列中取一個Popup,每個Popup顯示7秒。 

四,怎麼知道有新帖子 

在Web程序中,只能通過“拉”的技術,即定時向服務器發送請求——通過定時刷新或者是xmlhttp的Get。 
我們需要有個時間戳來記錄最後請求時間,這樣就好根據這個時間戳來獲取時間戳之後的帖子。 
如果每次根據時間戳來獲取最新帖子,服務器負荷比較大,因爲並不是每次請求都有新帖子的,優化一下,再給每個在線用戶設置有無新帖子、有無新留言的狀態位,當發表新帖子後更新每個人的“有無新帖”狀態位。這樣每次請求時先判斷有沒有新帖子,如果有新帖子,才獲取所有帖子的標題和內容簡要。 


使用Popup窗口創建無限級Web頁菜單

在Web上使用菜單可以極大地節約頁面的空間,同時也比較的符合用戶從Windows上繼承下來的UI操作體驗。在以往的Web頁菜單設計中,我們普遍使用div嵌套table的方式來實現菜單,這樣的菜單有個最致命的問題就是會被
<select>覆蓋。我們爲了解決這個問題,有時我們乾脆在顯示圖層菜單的同時隱藏頁面上的所有下拉列表框,在菜單消失的時候,再顯示他們。這個方法雖然可以解決問題,而其優化過後還可以只隱藏和下拉列表框相交的列表框,但是這些解決方法都不是十分的完美。還有些小問題,這樣的菜單定位很困難,因爲在<div>顯示的時候,用戶可以使用鼠標滾輪滾動頁面,這樣一來是否要讓<div>菜單和頁面滾動同步呢?如果不要,頁面被滾走了,菜單仍顯示在一個和自己毫不相關的位置上很是古怪。如果要同步,那麼噩夢就來了,因爲被滾動的區域不一定就是<body>區域,還可能是一些類似<div style="overflow:auto"><div>的區域,要算出菜單的位置將會非常的麻煩。 

下面將介紹的Popup來實現的Web頁菜單將完全解決
<div>做爲菜單容器時遇到的問題,Popup窗口是IE5.5及以後版本提供的一個新feature。什麼是popup呢?簡單說popup其實就是一個彈出窗口,它擁有以下特點(MSDN描述): 
·popup窗口在用戶點擊它自身之外的任何地方或另一個popup打開的時候會自動關閉; 
·popup在顯示的時候不能獲得焦點,所以用戶已focused的操作將繼續在其父窗口中執行; 
·組成popup的DHTML可以存儲在其父document或其他的document元素中; 
·popup窗口中不支持文本框一類的編輯框element; 
·不能選中popup窗口中的元素; 
·不能在popup窗口中navigate(點擊popup中的連接,不能讓更新的內容顯示到這個popup中); 
·popup窗口一旦顯示就不能移動和resize。 

這裏MSDN說的不全,而且有的地方不是很準確,popup窗口還有幾個重要的特性。它可以超出瀏覽器的窗口範圍而且也不會被下拉框、flash、IFrame等這些元素遮擋。實際上popup裏的內容是可以被選擇的,不知道MSDN說的不能選擇是啥意思
?。關於MSDN說popup不能獲得焦點也有點問題,其實是popup裏的編輯框類控件不能獲得焦點,而其它的非可編輯控件是可以獲得焦點的。而且popup顯示的時候,IE主窗口不能獲得鼠標的onmousewheel事件。 
這樣的一些特性,恰好表明了popup窗口非常的適合用來製作彈出菜單,並且由於popup窗口顯示的時候,IE窗口內的文檔是不能被移動的,這樣就不存在context menu的位置同步問題了,因爲畢竟popup窗口不能move(move位置需要hide以後在新的位置上重show),這個問題還比較討厭。 

使用popup窗口製作無限級別的菜單,有兩個問題要解決:一個是要能在一個IE中顯示多個Popup窗口,二是要能把窗口中的一些事件俘獲並執行我們腳本過程。MSDN在描述popup窗口特性時,第一條就說了只要有另一個popup窗口開啓,先前顯示的popup窗口就會自動關閉。這下怎麼辦呢?不過既然都說了要實現無限級的菜單了,辦法還是有的。對於popup,使用方式其實是很簡單的,他一共就只包含了兩個方法:hide()和show(...),和兩個屬性:document和isOpen。雖然在IE中我們連續的調用n次window.createPopup().show(...)只能出來一個popup窗口被顯示,可是我們可以調用popup.document.parentWindow的createPopup方法,它產生的popup窗口在顯示的時候就不會關閉前面已顯示的popup窗口,並且對於新的popup用這個方法可以繼續開啓child popup。這個問題再研究下去,會發現IE實現popup的一些怪異的地方(當然這些對於我們實現這個菜單關係不太大,只是覺得混亂)。 

比如我們在一個IE窗口中,
var popup = window.createPopup(); var win = popup.document.parentWindow; 我們會發現 window != win,對於多個popup可以共存,這個不相等還能理解,但是當我們調用win.resizeTo(...)的時候,我們發現父IE窗口被resize了。同樣我們在popup中select all,結果也是父IE窗口裏的內容被全選了@_@... 

使用Popup窗口創建無限級Web頁菜單(
2

上次我說到要使用popup在web中創建無限級菜單,兩個要解決的問題是多個popup窗口共存和popup中的事件的處理。其中多個popup共存的問題我已經講了可以使用popup.document的parentWindow來再createPopup,這個就算搞定了,而第二個問題就有些讓人討厭了,爲什麼呢? 

    我們通過createPopup創建的popup對象包含了一個document屬性,document其實就是html的容器。MSDN說:構建popup的DHTML可以存儲在其父document或其他的document中。這個話真是讓人不明白,其實就是說我們可以使用popup.document.body去append別的DHTML內容,比如:popup.document.body.innerHTML 
= '...'或popup.document.body.appendChild(...)。這裏又遇到了popup的一些怪異的特性,我們發現: var win = window; 
var doc = win.document;  
var popup = win.createPopup(); 
var popdoc = popup.document; 
var popwin = popdoc.parentWindow; 
var popwindoc = popwin.document;      結果popdoc != popwindoc,這都沒什麼了,不等就不等把,可是當我們調用popdoc.write和popwindoc.write後,去發現執行結果是一樣的,即數據被寫入了popup窗口中。不過還好這裏也不影響我們的菜單實現,就是怪異罷了。 

    上面的popdoc和popwindoc引用雖然不同,不過執行效果卻相同,都能按我們預期的效果修改popup。可是接下來我們發現popup.document.body的appandChild方法和innerHTML屬性向popup裏添加DHTML內容的效果就大不同了,這個不同和給我帶了很多的麻煩,使菜單的邏輯數據(JavaScript構建的菜單類)與UI表現(HTML元素構建的菜單的可視外觀)以及它們之間的事件傳遞變得亂糟糟的。 

    我們有兩個方法向popup裏添加html內容,一個是使用popup.document.body的innerHTML直接把html代碼賦到body中去;另一個辦法是使用popup.document.body的appendChild方法對dom進行操作。這裏要注意,必須使用popup自己的document對象來創建DHTML元素,才能使用appendChild來添加。比如我上面代碼中的popdoc和popwindoc雖然引用不相等,但是確實是popup的doucment對象,使用他們來createElement得到的對象,才能被appendChild到popup裏去。如果是使用doc來createElement得到的對象,在popup.docuemnt.body上去appendChild會得到一個運行時錯誤:Error: Invalid argument.。 

    爲什麼囉裏囉唆說了半天appendChild方法和innerHTML屬性呢?因爲他們各有各的好處,如果使用appendChild這種方式,我們可以在創建菜單類的數據的時候,使菜單的邏輯數據(JavaScript實現的類)和UI顯示元素(HTML)之間彼此引用起來,這樣在我們處理菜單事件的時候,會使程序和整個執行結構都變得比較清晰(這個在菜單處理事件的時候,我會再詳細說)。這樣一說,我們當然應該使用這種方法來append我們的菜單的內容了,可是我們又遇到了popup一個讓人抓狂的問題。使用popup.document.body.appendChild方法把DHTML內容導入後,我們事先賦給DHMTL元素的屬性有些會失效,其中包括nowrap, onstartselect, rules等,這三個屬性的失效,十分嚴重的影響了菜單UI的呈現,下圖就是使用appendChild後popup窗口裏得到的效果,左邊是在IE裏我們希望的正確效果。  

所以不得不放棄了appendChild方法的使用,改用popup.document.body.innerHTML直接賦值html的辦法,可是這種方法就不能在對象引用關係上建立菜單邏輯數據和UI元素之間的聯繫,因爲對象引用雖然能被存儲在html元素的屬性中,可是當以字符串方式來複制html元素時,html元素上attach的事件和屬性裏存放的對象引用就都丟失了,所以只能使用另外的辦法來關聯他們。於是我們實現了一個叫__MenuCache__的類似hash table的全局類來管理它們之間的一一對應關係。  


用Popup對象構建網頁右鍵菜單

代碼如下: 

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> 
<html> 
<head> 
<TITLE>Popup對象實現右鍵菜單</TITLE> 
<script language="JavaScript"> 
var oPopup = window.createPopup(); 
function contextMenu() 


var left = event.offsetX+10
var top = event.offsetY+10
oPopup.document.body.innerHTML 
= oContext.innerHTML; 
oPopup.show(left, top, 
12080, window.document.body); 

}
 
</script> 
</head> 
<body oncontextmenu="contextMenu(); return false;"> 
<h1>Popup對象實現右鍵菜單</h1> 
單擊鼠標右鍵查看效果 
<div ID="oContext" style="DISPLAY: none; BACKGROUND: #e4e4e4; "> 
<div onmouseover="this.style.background='gold'" 
onmouseout
="this.style.background='#e4e4e4'" 
<span onclick='parent.location.href="http://www.zol.com.cn"'> 
中關村在線
</span> 
</div> 
<div onmouseover="this.style.background='gold'" 
onmouseout
="this.style.background='#e4e4e4'" 
<span onclick="parent.location.href='http://www.cfan.com.cn'"> 
電腦愛好者
</span> 
</div> 
<div onmouseover="this.style.background='gold';" 
onmouseout
="this.style.background='#e4e4e4';"> 
<span onclick="parent.location.href='http://www.sina.com.cn'"> 
新浪網
</span> 
</div> 
<div onmouseover="this.style.background='gold'" 
onmouseout
="this.style.background='#e4e4e4'" 
<span onclick="parent.location.href='http://www.xinhuanet.com'"> 
新華網
</span> 
</div> 

</div> 
</body> 
</html> 



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章