2013年3月25日 星期一

網頁遮罩的實作


畫面運用 javascript 的情況日益普遍, 許多 javascript 都需等待整個網頁下載完畢後才能開始運行, 於是我們習慣將這些 script 寫在網頁的最後面, 其中不乏按鈕動作需執行的 script 問題來了,當網頁還在下載中,而某些按鈕已經出現了, 按鈕相應的script還沒下載完,而user看到「獵物」就迫不及待操作, 後果就是發生 script error,有些前端驗證邏輯沒做就送到後台去了, 引發不少後遺症。 為堵絕這種問題,就出現了螢幕遮罩這東東, 網頁一出現就會有用個遮罩擋住網頁, 直至網頁完全下載,遮罩才會消失, 目前 de script 已加了這功能,這篇是簡單介紹這個遮罩的製作原理。

製作遮罩必須清楚把握兩個地點,第一、網頁的最源頭,第二、網頁的最尾巴。
在網頁的最源頭出現時,立刻放置一個「遮罩」,並在網頁的最尾巴處把「遮罩」拿掉,就這麼簡單。

網頁的最源頭很好判斷,目前每支jsp都會include dzjjmenu.jsp/dzjjmain.jsp,這兩支都會引用若干的常用jss,只需在某支必定引用的jss加上「遮罩」就行了,接下來的問題就是:怎麼能在網頁的最尾巴裡把「遮罩」拿掉,或更確切的說,怎麼在網頁完全下載後做事情?

這裡我偷偷向jquery學習了,它用了一個較 tracky 的手法,程式碼如下:
function onPageReady(){
     try {
                document.documentElement.doScroll("left");
             // 做你想在網頁下載後要做的事情;
           } catch( error ) {
                setTimeout( arguments.callee, 100 );
                return;
           }
}

document.documentElement.doScroll("left");
網頁尚未下載完畢的話,執行到這一行就會發生error,就跳進 catch(error)裡,而 setTimeout( arguments.callee, 100 ); 意思即隔100毫秒後再重新執行onPageReady(),所以網頁下載很慢的話,這個function就會每隔一段時間執行一次,直到沒有error為止。

第二部份來看看遮罩的製作及移除,目前我採用了iframe當作遮罩,在IE的世界裡,iframe有著尊貴崇高的地位,他的層級淩駕任何元素,用它來當遮罩最棒不過了,為了讓遮罩有點矇矓美,可將opacity設成50,於是在網頁的一開頭就寫下了這段:
document.write("");

接著在網頁下載後,就是要清掉這個iframe,清掉這個iframe直覺上的手法是將它的style.display設為none,在我本機測通過後就上線了,結果發現在某些電腦的IE上,同時下載多個摺頁(每個摺頁都有iframe)時,某些摺頁無法把遮罩拿掉,遮罩永遠Hang在畫面上,前後持續了兩天才找出原因,問題出在哪呢?

我也不知道,只是後來我不用style.display這招了,我試著把iframe整個remove,後來就解了,這次經驗我得到一個結論: style.display在某些狀況是會失效的,尤其是一開始網頁也是被隱藏的情況下(未切換到的那些摺頁),附上這段程式碼:

var iframeMask=document.getElementById("_de_mask") ;
if(iframeMask==null){
     document.write("");
}
function deCloseMask(){
     try {
                document.documentElement.doScroll("left");        document.body.removeChild( document.getElementById("_de_mask") );
           } catch( error ) {
                setTimeout( arguments.callee, 100 );
                return;
           }
}
deCloseMask();


沒有留言: