[JavaScript]自定義MessageBox

前言:

    繼上文([JavaScript]自定義Title的顯示方式)之後,我的工作是進一步增強一些IE所不能提供的東東.

    還記得Windows下的MessageBox嘛?

    IE呢?Alert?Confirm? 是不是好醜呢?

    不過醜就算了,關鍵是還不好用.

    本次的目標是,提供好看又好用的Web版的Windows MessageBox.(已測試,兼容IE和FF)

正文:

    首先自然是先畫好Html下的對話框樣子了(用層來模擬):


    畫得不專業,先用着,反正後面可以通過css來調整.

    接下來的工作就是需要通過Javascript動態輸入這個層的內容.首先參考[JavaScript]自定義Title的顯示方式中的方式,代碼雖然很多,不過只不過比[JavaScript]自定義Title的顯示方式多了幾個層而已,大同小異:
   

  1
  2KMessageBox = {
  3  name: "KMessageBox",
  4  capiton : "消息框",
  5  content: "提示消息",
  6  msgbox : null,
  7  msgcaptioninfo:null,
  8  msgcontent:null,
  9  msgContenttxtmsg:null,
 10  msgbuttonyes:null,
 11  msbbuttonno:null,
 12  msgico:null 
 13}
;
 14
 15KMessageBox.init = function () {
 16    var msgNameSpaceURI = "http://www.w3.org/1999/xhtml";
 17    
 18    if(!msgContainerID)var msgContainerID= "KMessageBox"; }
 19
 20    if(!msgCaptionID)var msgCaptionID= "KMessageBox_caption"; }
 21    if(!msgCaptionInfoID){var msgCaptionInfoID = "KMessageBox_caption_info";}
 22    if(!msgContentID)var msgContentID = "KMessageBox_content"; }
 23    if(!msgContentTxtID)var msgContentTxtID= "KMessageBox_content_txt"; }
 24    if(!msgContentTxtICOID){var msgContentTxtICOID="KMessageBox_content_txt_ico"};
 25    if(!msgContentTxtMsgID){var msgContentTxtMsgID="KMessageBox_content_txt_msg"};
 26    if(!msgButtons){var msgButtonsID="KMessageBox_buttons"};
 27    if(!msgButtonYes){var msgButtonYesID="KMessageBox_buttons_yes"};
 28    if(!msgButtonNo){var msgButtonNoID="KMessageBox_buttons_no"};    
 29    if(!msgButtonOK){var msgButtonOKID="KMessageBox_buttons_ok"};    
 30
 31    var msgContainer = $(msgContainerID);
 32    if(!msgContainer) {
 33      msgContainer = document.createElementNS ? document.createElementNS(msgNameSpaceURI, "div") : document.createElement("div");
 34      msgContainer.setAttribute("id", msgContainerID);
 35      msgContainer.setAttribute("style","MARGIN: 0px auto; POSITION: absolute; TEXT-ALIGN: center;");
 36
 37
 38    var msgCaption = $(msgCaptionID);
 39
 40    if(!msgCaption){
 41      msgCaption = document.createElementNS ? document.createElementNS(msgNameSpaceURI, "div") : document.createElement("div") ;
 42      msgCaption.setAttribute("id",msgCaptionID);
 43      Element.addClassName(msgCaption,"caption");      
 44
 45      
 46      var msgCaptionInfo = $(msgCaptionInfoID);
 47      if(!msgCaptionInfo){
 48      msgCaptionInfo = document.createElementNS ? document.createElementNS(msgNameSpaceURI, "div") : document.createElement("div") ;
 49      msgCaptionInfo.setAttribute("id",msgCaptionInfoID);
 50      Element.addClassName(msgCaptionInfo,"info");
 51      msgCaption.appendChild(msgCaptionInfo);
 52      }

 53      msgContainer.appendChild(msgCaption);
 54      
 55    }

 56    
 57    var msgContent = $(msgContentID);
 58
 59    if(!msgContent){
 60      msgContent= document.createElementNS ? document.createElementNS(msgNameSpaceURI, "div") : document.createElement("div") ;
 61      msgContent.setAttribute("id",msgContentID);
 62      Element.addClassName(msgContent,"content");
 63      
 64      var msgContentTxt = $(msgContentTxtID);
 65      
 66      if(!msgContentTxt ){
 67      msgContentTxt = document.createElementNS ? document.createElementNS(msgNameSpaceURI, "div") : document.createElement("div") ;
 68      msgContentTxt.setAttribute("id",msgContentTxtID);
 69      Element.addClassName(msgContentTxt,"txt");
 70           
 71      var msgContentTxtICO = $(msgContentTxtICOID);
 72      if(!msgContentTxtICO)
 73      {
 74         msgContentTxtICO= document.createElementNS ? document.createElementNS(msgNameSpaceURI, "img") : document.createElement("img") ;
 75         msgContentTxtICO.setAttribute("id",msgContentTxtICOID);
 76         msgContentTxtICO.setAttribute("src","icon_alarm.gif");
 77         msgContentTxtICO.setAttribute("align","absMiddle");
 78         msgContentTxtICO.setAttribute("style","height:52px;width:64px;background-image:url('icon_big_info.gif');");
 79         msgContentTxt.appendChild(msgContentTxtICO);
 80      }

 81      
 82      var msgContentTxtMsg= $(msgContentTxtMsgID);
 83      if(!msgContentTxtMsg)
 84      {
 85         msgContentTxtMsg= document.createElementNS ? document.createElementNS(msgNameSpaceURI, "span") : document.createElement("span") ;
 86         msgContentTxtMsg.setAttribute("id",msgContentTxtMsgID);
 87         
 88         msgContentTxt.appendChild(msgContentTxtMsg);
 89      }

 90
 91
 92      var msgButtons = $(msgButtonsID);
 93      if(!msgButtons)
 94      {
 95         msgButtons = document.createElementNS ? document.createElementNS(msgNameSpaceURI, "div") : document.createElement("div") ;
 96         msgButtons.setAttribute("id",msgButtonsID);
 97         Element.addClassName(msgButtons,"btnlist");
 98         var msgButtonYes = $(msgButtonYesID);
 99          if(!msgButtonYes)
100          {
101            msgButtonYes= document.createElementNS ? document.createElementNS(msgNameSpaceURI, "input") : document.createElement("input") ;
102            msgButtonYes.setAttribute("id",msgButtonYesID);
103            msgButtonYes.setAttribute("type","button");
104            msgButtonYes.setAttribute("value","YES");
105            Element.addClassName(msgButtonYes,"input_set");
106                    
107            msgButtons.appendChild(msgButtonYes);             
108         }

109
110         var msgButtonNo = $(msgButtonNoID);
111          if(!msgButtonNo)
112          {
113            msgButtonNo= document.createElementNS ? document.createElementNS(msgNameSpaceURI, "input") : document.createElement("input") ;
114            msgButtonNo.setAttribute("id",msgButtonNoID);
115            msgButtonNo.setAttribute("type","button");
116            msgButtonNo.setAttribute("value","NO");
117            Element.addClassName(msgButtonNo,"input_set");
118            
119            msgButtons.appendChild(msgButtonNo); 
120            
121         }

122         
123         var msgButtonOK= $(msgButtonOKID);
124          if(!msgButtonOK)
125          {
126            msgButtonOK= document.createElementNS ? document.createElementNS(msgNameSpaceURI, "input") : document.createElement("input") ;
127            msgButtonOK.setAttribute("id",msgButtonOKID);
128            msgButtonOK.setAttribute("type","button");
129            msgButtonOK.setAttribute("value","OK");
130            Element.addClassName(msgButtonOK,"input_set");
131            
132            msgButtons.appendChild(msgButtonOK); 
133            
134         }

135
136
137         msgContentTxt.appendChild(msgButtons);
138      }

139      
140      msgContent.appendChild(msgContentTxt);
141      }

142
143      
144      msgContainer.appendChild(msgContent);
145    }

146
147     document.getElementsByTagName("body").item(0).appendChild(msgContainer);
148    }

149       
150    this.msgbox = $(this.name);
151    this.msgcaptioninfo = $(msgCaptionInfoID);
152    this.msgContenttxtmsg= $(msgContentTxtMsgID);
153    this.msgbuttonyes = $(msgButtonYesID);
154    this.msgbuttonno = $(msgButtonNoID);
155    this.msgbuttonok = $(msgButtonOKID);
156    this.msgico = $(msgContentTxtICOID);
157    Element.hide(this.msgbox);
158   
159}

160
161

    接下來應該爲MessageBox提供行爲能力.我們需要模擬Confirm和Alert.
    原始的Confrim需要返回false或者true來決定是否要運行postback事件.
    在這裏我轉換了一下思路,不返回值,而是直接將postback事件的腳本(_doPostBack('',''))傳入MessageBox,並綁定到相關的按鈕上.所以我們的需要接受傳入的參數主要有:消息標題,消息內容,按鈕事件
    OK,接下來構造Javascript中MessageBox的ShowConfirm函數:

 1KMessageBox.ShowConfirm = function (imgdir,caption,msg,YesClick,NoClick) {
 2    
 3    if (!this.msgbox ) return;
 4    
 5    this.msgcaptioninfo.innerHTML = caption;
 6    this.msgContenttxtmsg.innerHTML = msg;
 7    //爲了提示消息前面的圖片可以適應實際的相對位置,傳入程序父目錄,主要爲封裝爲Server控件做準備
 8       if(imgdir != "")
 9       {
10         this.msgico.setAttribute("src",imgdir+"/kinnsoft_client/KMessageBox/icon_alarm.gif");
11       }

12       else
13       {
14         this.msgico.setAttribute("src","/kinnsoft_client/KMessageBox/icon_alarm.gif");
15       }

16    
17        //使用prototype類庫
18    Element.show(this.msgbox);
19    Element.show(this.msgbuttonyes);
20    Element.show(this.msgbuttonno);
21    Element.hide(this.msgbuttonok);
22    
23    var x=0,y=0;
24    x = (document.documentElement.scrollLeft || document.body.scrollLeft);
25    y = (document.documentElement.scrollTop || document.body.scrollTop);
26    
27        /*一下這段這麼複雜的處理方法,是爲了符合最新web標準,因爲在aspx頁面中會默認加入
28<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
29新的標準中不支持document.body.clientHeight 屬性,它是MSIE所有的
30
31*/

32    var theWidth=0,theHeight=0;
33    
34    if (window.innerWidth) 
35    
36      theWidth = window.innerWidth 
37      theHeight = window.innerHeight 
38    }
 
39    else if (document.documentElement && document.documentElement.clientWidth) 
40    
41      theWidth = document.documentElement.clientWidth 
42      theHeight = document.documentElement.clientHeight 
43    }
 
44    else if (document.body) 
45    
46      theWidth = document.body.clientWidth 
47      theHeight = document.body.clientHeight 
48    }

49    
50       //做div居中處理
51    this.msgbox.style.left = (theWidth  - this.msgbox.offsetWidth)/2+x;
52    this.msgbox.style.top = (theHeight - this.msgbox.offsetHeight)/2+y; 
53
54      //綁定傳入的事件
55    this.msgbuttonyes.onclick = YesClick;//function(){ alert('yes');};
56    this.msgbuttonno.onclick = NoClick;
57      //綁定隱藏div的事件,使用prototype類庫
58    Event.observe(this.msgbuttonyes,"click",function(){KMessageBox.Hide();},true);
59    Event.observe(this.msgbuttonno,"click",function(){KMessageBox.Hide();},true);
60}

   有了顯示還需要做隱藏處理,即上面調用的KMessageBox.Hide();
  
 1KMessageBox.Hide = function()
 2{
 3    if (!this.msgbox ) return;
 4    Element.hide(this.msgbox);
 5    //detach 事件,防止IE 內存泄漏
 6    Event.stopObserving(this.msgbuttonyes,"click",function(){KMessageBox.Hide();},true)
 7    Event.stopObserving(this.msgbuttonno,"click",function(){KMessageBox.Hide();},true)
 8    Event.stopObserving(this.msgbuttonok,"click",function(){KMessageBox.Hide();},true)
 9}

10

    至於模擬Alert,就可以模仿ShowConfirm來做了,so easy
   
    ok,整個MessageBox 類看起來已經像模像樣了.運行一下...
   
     噫,不對,好像缺了點什麼....沒錯,它不是ShowModal類型的...用戶還可以任意點下面的頁面元素.

     這個怎麼模擬?

     當然還是div了...做一個整個頁面大小的div覆蓋在所有頁面元素之上,MessageBox層之下.
    
     不過有個弊端,div不能覆蓋select控件,那隻好搬出iframe了..所謂道高一尺魔高一丈

   
 1function DialogModal()
 2    this.blankImgHandle = null
 3    this.tags = new Array("applet""iframe""select","object","embed");  
 4}

 5
 6 
 7DialogModal.Show = function() 
 8{     
 9debugger;
10        var NameSpaceURI = "http://www.w3.org/1999/xhtml";
11        this.blankImgHandle = document.createElementNS ? document.createElementNS(NameSpaceURI, "iframe") : document.createElement("iframe") ;//iframe
12        this.blankImgHandle.setAttribute("id","blankImgHanldle");
13        with (this.blankImgHandle.style)
14            position = "absolute"
15            left     = 0
16            top      = (document.documentElement.scrollTop || document.body.scrollTop); 
17            height   = "100%"; //這邊用100%在 標準生成的aspx頁面好像比起效果,去掉doctype那句就可以,所以我直接設置一個分辨率即1024X768
18            width    = "100%"
19            zIndex   = "9999"; //這個zIndex比頁面所有元素大,但是要比MessageBox小,保證MessageBox 不被罩住
20            filter   = "progid:DXImageTransform.Microsoft.Alpha(style=0,opacity=40)"
21            opacity  = "0.1";             
22        }
          
23         
24       document.getElementsByTagName("body").item(0).appendChild(this.blankImgHandle);         
25   }
         
26         
27DialogModal.Close = function(){                
28      if (this.blankImgHandle) 
29      
30          Element.remove(this.blankImgHandle);
31          this.blankImgHandle = null;
32      }
             
33  }

34

    在MessageBox中Show的時候,調用DialogModal.Show,Hide的時候調用DialogModal.Hide 即ok了.

    有了上面的兩個Javascript類,我們就可以很好的做服務端的封裝了,取到control的dopostback函數,直接傳入給ShowConfrim就可以了.
   
1//ShowConfirm客戶端事件
2private string JS_CONFIRM = "KMessageBox.ShowConfirm('{0}','{1}','{2}',{3},{4});return false;";
3
4//獲取DoPostBack事件,這邊還有個難點,怎麼取得客戶端驗證事件,目前我還沒有解決
5strOnClickScript = "function(){" + Page.ClientScript.GetPostBackEventReference(control, ""+ ";}";
6//註冊MessageBox事件,
7 control.Attributes["onclick"+= string.Format(JS_CONFIRM, this.mImgDir, caption, content, strOnClickScript, "function(){}");

源碼:

代碼插入比較慢,而且經常ShowDialogModal框不返回,暈死.....直接down吧: KMessageBox_Source

KMessageBox.js

 

KMessageBox.css

 

 

請詳細看原文:

http://www.cnblogs.com/walkingboy/archive/2006/08/10/472908.html

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