原文地址為:關於js關閉視窗的事件和用法
Onunload與Onbeforeunload
Onbeforeunload也是在頁面重新整理或關閉時呼叫,Onbeforeunload是正要去伺服器讀取新的頁面時呼叫,此時還沒開始讀取;而onunload則已經從伺服器上讀到了需要載入的新的頁面,在即將替換掉當前頁面時呼叫。Onunload是無法阻止頁面的更新和關閉的。而 Onbeforeunload 可以做到。曾經做一個考試系統,涉及到防止使用者半途退出考試(有意或者無意),程式碼如下:
你可能認為最流行的語言是Java、Basic、C、C 之類的高階語言,實質上Javascript也是當之無愧的流行語言。它的奧妙遠比你想象中的還要多。如果你看過Google的GMail和Map,你要知道Javascript也可以讓世界變得觸手可及將技術變得爐火燉青的地步。
本文將從實際中經常遇到的幾個問題入手,著手用Javascript指令碼巧妙解決這些問題,以此拋磚引玉希望給大家帶來幫助。
強制關閉視窗後清除使用者Session
一般的會員式網站,在會員登陸成功後都會建立會話或者Cookie,然後可以直接在站點間共享會員的資料。而這些資料通常放置在伺服器記憶體中。在會員退出時,按照正常的設計思路是執行退出功能釋放會員登陸成功後所使用的伺服器和客戶端等相關資源。現在經常遇到的問題是,使用者經常直接關閉網頁而不是我們所期望執行的退出程式。這樣就會造成使用者登陸後的資源不會及時釋放而加重伺服器負荷,隨著問題的進一步累積逐步的放大從而影響伺服器的效能。
有幸的是在網路上找到針對IE瀏覽器捕獲使用者使用Alt F4、標題欄按右鍵關閉、雙擊標題欄、直接按關閉按鈕的事件的方法。當然對於一些直接關閉程序或者最小化的方式在工作列進行關閉是不能正常捕獲的,但現在所涉及的解決方案,可以解決大多數存在的問題。
<script language=”javascript”>
function window.onUnload()
{
var newWindow;
if((window.screenLeft>=10000 && window.screenTop>=10000)||event.altKey)
{
newWindow=window.open(‘退出程式地址’,’網頁名稱’,
‘width=0,height=0,top=4000,left=4000’);//新視窗將在視區之外開啟
newWindow.opener=null;
sleep(5000);//執行休眠操作以便能夠處理完新開啟視窗執行程式碼
newWindow.close();//新視窗關閉
……//其他需要執行的退出程式序列可參考上面進行新增
}
}
function sleep(milisecond)
{
var currentDate,beginDate=new Date();
var beginHour,beginMinute,beginSecond,beginMs;
var hourGaps,minuteGaps,secondGaps,msGaps,gaps;
beginHour=beginDate.getHours();
beginMinute=beginDate.getMinutes();
beginSecond=beginDate.getSeconds();
beginMs=beginDate.getMilliseconds();
do
{
currentDate=new Date();
hourGaps=currentDate.getHours() – beginHour;
minuteGaps=currentDate.getMinutes() – beginMinute;
secondGaps=currentDate.getSeconds() – beginSecond;
msGaps=currentDate.getMilliseconds() – beginMs;
if(hourGaps<0) hourGaps =24; //考慮進時進分進秒的特殊情況
gaps=hourGaps*3600 minuteGaps*60 secondGaps;
gaps=gaps*1000 msGaps;
}while(gaps<milisecond);
}
</script>
說明:
window.screenLeft = 10000 邊框寬 (2×2) = 10004
window.screenTop = 10000 工具欄高 標題欄高 = 10097
需要說明的,在onBeforeUnload中螢幕這些座標屬性都是正常數值。
screenLeft:獲取瀏覽器客戶區左上角相對於螢幕左上角的 x 座標。
screenTop:獲取瀏覽器客戶區左上角相對於螢幕左上角的 y 座標。
如果需使用window.location指定URL進行處理,那麼需放在onBeforeUnload 事件中而不是onUnload事件。在onUnload裡不要使用window.close,因為物件銷燬前會立即觸發該事件,無法有效執行由被銷燬物件所引發的引用。而onBeforeUnload是頁面將要被解除安裝前觸發的事件。解決的方法是新開一個視窗再將之關閉。而所謂的清除實質上就是把做好退出功能的頁面,直接以開啟新視窗方式的呼叫。在呼叫到關閉的時候要儘可能停留一段時間確保全部程式碼被有效觸發。需要說明的是onUnload事件,在頁面前進、後退、重新整理、轉向、關閉後都會觸發。因此要捕獲強制關閉視窗的特殊事件,需要在程式碼上加上判斷條件,以保證在符合情形的條件下觸發。該段程式碼已經成功地進行測試。
對話方塊取值
在網頁中,經常會使用一種類似對話方塊的設計,為了方便使用者輸入、快速選擇經常會開啟一個頁面,再做出選擇後關閉該頁面並將使用者選擇的資料傳遞到父頁面做後續處理。
前些時間,看到一種比較原始的方法,不是很通用,直接在子頁面裡修改父頁面某個控制元件的數值再加之關閉。這樣做的缺點是,不適合大規模的呼叫。假設父頁面有開始日期與結束日期兩個框需要接受日曆頁面的輸入,那麼你需要做兩個不同的日曆頁面才能保證兩個框都有對應的資料。這在大型工程中是不好的設計方法。多樣化的外部環境,如果不考慮通用的方法,將增加維護的難度同時降低開發的效率。
IE支援模態視窗,在對話方塊的頁面中通過設定的window.returnValue的數值,在父窗體中靠呼叫window.showModalDialog獲取返回值,無效將返回null(開啟的頁面不存在)或undefined(window.returnValue沒有設定)。我設計了getDialog函式,用於獲取子窗體的返回值,異常或者無效將返回空串否則為正常返回資料。
而原先的window.open方式,我也改進一下設計了getWindowReturnValue,通過偵聽子窗體的window.returnValue,如果有資料將開始終止。如果窗體仍然開啟則自動關閉。同樣兩個函式都需要進行正確的設定window.returnValue。
//在IE中開啟模態對話方塊並返回資料
//需要在開啟頁面設定window.returnValue,錯誤或無效返回空
function getDialog(url)
{
var returnValue;
try
{
returnValue=window.showModalDialog(url);
}catch(e)
{ return “”; }
return (returnValue==null||returnValue==”undefined”)?””:returnValue;
}
//使用window.open來獲取子視窗資料,需要動態設定window.returnValue
//引數為:地址、名稱、寬度、高度,不設定寬度與高度請設為0。
function getWindowReturnValue(url,name,width,height)
{
var opener=null;
var spec=”toolbar=0,menubar=0,scrollbars=0,resizeable=0″;
var returnValue=null;
if(width>0) spec=spec “,width=” String.valueOf(width);
if(height>0)
{
spec=spec “,height=” String.valueOf(height);
}
opener=window.open(url,name,spec);
while(!opener.window.closed)
{
returnValue=opener.window.returnValue;
if(returnValue!=null&&returnValue.length>0) break;
}
if(!opener.window.closed) opener.window.close();
return returnValue;
}
轉載請註明本文地址:關於js關閉視窗的事件和用法
写评论
很抱歉,必須登入網站才能發佈留言。