前言:
继上文([JavaScript]自定义Title的显示方式)之后,我的工作是进一步增强一些IE所不能提供的东东.
还记得Windows下的MessageBox嘛?
IE呢?Alert?Confirm? 是不是好丑呢?
不过丑就算了,关键是还不好用.
本次的目标是,提供好看又好用的Web版的Windows MessageBox.(已测试,兼容IE和FF)
正文:
首先自然是先画好Html下的对话框样子了(用层来模拟):
画得不专业,先用着,反正后面可以通过css来调整.
接下来的工作就是需要通过Javascript动态输入这个层的内容.首先参考[JavaScript]自定义Title的显示方式中的方式,代码虽然很多,不过只不过比[JavaScript]自定义Title的显示方式多了几个层而已,大同小异:
1
2
KMessageBox
=
{
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
15
KMessageBox.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

2



3

4

5

6

7

8

9

10

11

12

13

14

15



16

17

18



19

20



21



22



23



24



25



26



27



28



29



30

31

32



33

34

35

36

37

38

39

40



41

42

43

44

45

46

47



48

49

50

51

52

53

54

55

56

57

58

59



60

61

62

63

64

65

66



67

68

69

70

71

72

73



74

75

76

77

78

79

80

81

82

83

84



85

86

87

88

89

90

91

92

93

94



95

96

97

98

99

100



101

102

103

104

105

106

107

108

109

110

111

112



113

114

115

116

117

118

119

120

121

122

123

124

125



126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

接下来应该为MessageBox提供行为能力.我们需要模拟Confirm和Alert.
原始的Confrim需要返回false或者true来决定是否要运行postback事件.
在这里我转换了一下思路,不返回值,而是直接将postback事件的脚本(_doPostBack('',''))传入MessageBox,并绑定到相关的按钮上.所以我们的需要接受传入的参数主要有:消息标题,消息内容,按钮事件
OK,接下来构造Javascript中MessageBox的ShowConfirm函数:
1
KMessageBox.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
}



2

3

4

5

6

7

8

9



10

11

12

13



14

15

16

17

18

19

20

21

22

23

24

25

26

27


28

29

30

31

32

33

34

35



36

37

38

39

40



41

42

43

44

45



46

47

48

49

50

51

52

53

54

55

56

57

58



59



60

有了显示还需要做隐藏处理,即上面调用的KMessageBox.Hide();
1
KMessageBox.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

2



3

4

5

6



7



8



9

10

至于模拟Alert,就可以模仿ShowConfirm来做了,so easy
ok,整个MessageBox 类看起来已经像模像样了.运行一下...
噫,不对,好像缺了点什么....没错,它不是ShowModal类型的...用户还可以任意点下面的页面元素.
这个怎么模拟?
当然还是div了...做一个整个页面大小的div覆盖在所有页面元素之上,MessageBox层之下.
不过有个弊端,div不能覆盖select控件,那只好搬出iframe了..所谓道高一尺魔高一丈
1
function
DialogModal()
{
2
this.blankImgHandle = null;
3
this.tags = new Array("applet", "iframe", "select","object","embed");
4
}
5
6
7
DialogModal.Show
=
function
()
8
{
9
debugger;
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
27
DialogModal.Close
=
function
()
{
28
if (this.blankImgHandle)
29
{
30
Element.remove(this.blankImgHandle);
31
this.blankImgHandle = null;
32
}
33
}
;
34



2

3

4

5

6

7

8



9

10

11

12

13



14

15

16

17

18

19

20

21

22

23

24

25

26

27



28

29



30

31

32

33

34

在MessageBox中Show的时候,调用DialogModal.Show,Hide的时候调用DialogModal.Hide 即ok了.
有了上面的两个Javascript类,我们就可以很好的做服务端的封装了,取到control的dopostback函数,直接传入给ShowConfrim就可以了.
1
//
ShowConfirm客户端事件
2
private
string
JS_CONFIRM
=
"
KMessageBox.ShowConfirm('{0}','{1}','{2}',{3},{4});return false;
"
;
3
4
//
获取DoPostBack事件,这边还有个难点,怎么取得客户端验证事件,目前我还没有解决
5
strOnClickScript
=
"
function(){
"
+
Page.ClientScript.GetPostBackEventReference(control,
""
)
+
"
;}
"
;
6
//
注册MessageBox事件,
7
control.Attributes[
"
onclick
"
]
+=
string
.Format(JS_CONFIRM,
this
.mImgDir, caption, content, strOnClickScript,
"
function(){}
"
);

2

3

4

5

6

7

源码:
代码插入比较慢,而且经常ShowDialogModal框不返回,晕死.....直接down吧: KMessageBox_Source


1

2



3

4

5

6

7

8

9

10

11

12

13

14

15



16

17

18



19

20



21



22



23



24



25



26



27



28



29



30

31

32



33

34

35

36

37

38

39

40



41

42

43

44

45

46

47



48

49

50

51

52

53

54

55

56

57

58

59



60

61

62

63

64

65

66



67

68

69

70

71

72

73



74

75

76

77

78

79

80

81

82

83

84



85

86

87

88

89

90

91

92

93

94



95

96

97

98

99

100



101

102

103

104

105

106

107

108

109

110

111

112



113

114

115

116

117

118

119

120

121

122

123

124

125



126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161



162

163

164

165

166

167

168

169

170



171

172

173

174



175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190



191

192

193

194

195



196

197

198

199

200



201

202

203

204

205

206

207

208

209

210

211



212



213

214

215



216

217

218

219

220

221



222

223

224

225



226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243



244

245

246

247

248



249

250

251

252

253



254

255

256

257

258

259

260

261

262



263

264

265

266

267



268

269

270

271



272



273



274

275

276

277



278

279

280

281

282

283

284



285

286

287

288

289



290

291

292

293

294

295

296

297

298

299

300

301

302

303



304

305



306

307

308

309

310

311

312



313



1

2

3



4

5

6

7

8

9

10

11

12

13

14

15



16

17

18

19

20

21

22

23



24

25

26

27

28

29

30



31

32

33

34

35

36

37

38

39

40



41

42

43

44

45

46

47

48



49

50

51

52

53



54

55



56

57

58



59

60

61

62

63

64

65



66

67

68

69

70


71

72

73

74

75

76



77

78

79

80

81

82

请详细看原文:
http://www.cnblogs.com/walkingboy/archive/2006/08/10/472908.html