利用ASP.NET实现无刷新更新页面 (2)
上篇写道怎样用ASP.NET来实现页面的局部刷新,现在来说说它的实现机制。看下面的代码:
1 protected void Page_Load(object sender, EventArgs e)
2 {
3 txtTime.Value = DateTime.Now.ToString();
4
5 string callBackRef
6 = ClientScript.GetCallbackEventReference(this, string.Empty, "getTime", string.Empty);
7 btnGetTime.Attributes["onclick"] = callBackRef;
8 }
2 {
3 txtTime.Value = DateTime.Now.ToString();
4
5 string callBackRef
6 = ClientScript.GetCallbackEventReference(this, string.Empty, "getTime", string.Empty);
7 btnGetTime.Attributes["onclick"] = callBackRef;
8 }
在page_load事件中,我们给按钮btnGetTime的onclick属性(事件)赋值。这个值是通过ClientScript获得的客户端CallBack函数引用。再看客户端生成的情况:
1 <div>
2 <input name="txtTime" type="text" id="txtTime" readonly="readonly" value="2006-12-20 21:25:53" />
3 <input name="btnGetTime" type="button" id="btnGetTime" value="Get"
4 onclick="WebForm_DoCallback('__Page',"",getTime,"",null,false)" />
5 </div>
2 <input name="txtTime" type="text" id="txtTime" readonly="readonly" value="2006-12-20 21:25:53" />
3 <input name="btnGetTime" type="button" id="btnGetTime" value="Get"
4 onclick="WebForm_DoCallback('__Page',"",getTime,"",null,false)" />
5 </div>
我们可以看到按钮btnGetTime的onclick事件将会调用WebForm_DoCallback函数。之所以把这篇文章放到AJAX分类中来就是因为这个函数了,现在看看这个函数是如何实现的:
1
var __pendingCallbacks = new Array();
2
var __synchronousCallBackIndex = -1;
3
function WebForm_DoCallback(eventTarget, eventArgument, eventCallback, context, errorCallback, useAsync) {
4
var postData = __theFormPostData +
5
"__CALLBACKID=" + WebForm_EncodeCallback(eventTarget) +
6
"&__CALLBACKPARAM=" + WebForm_EncodeCallback(eventArgument);
7
if (theForm["__EVENTVALIDATION"]) {
8
postData += "&__EVENTVALIDATION=" + WebForm_EncodeCallback(theForm["__EVENTVALIDATION"].value);
9
}
10
var xmlRequest,e;
11
try {
12
xmlRequest = new XMLHttpRequest();
13
}
14
catch(e) {
15
try {
16
xmlRequest = new ActiveXObject("Microsoft.XMLHTTP");
17
}
18
catch(e) {
19
}
20
}
21
var setRequestHeaderMethodExists = true;
22
try {
23
setRequestHeaderMethodExists = (xmlRequest && xmlRequest.setRequestHeader);
24
}
25
catch(e) {}
26
var callback = new Object();
27
callback.eventCallback = eventCallback;
28
callback.context = context;
29
callback.errorCallback = errorCallback;
30
callback.async = useAsync;
31
var callbackIndex = WebForm_FillFirstAvailableSlot(__pendingCallbacks, callback);
32
if (!useAsync) {
33
if (__synchronousCallBackIndex != -1) {
34
__pendingCallbacks[__synchronousCallBackIndex] = null;
35
}
36
__synchronousCallBackIndex = callbackIndex;
37
}
38
if (setRequestHeaderMethodExists) {
39
xmlRequest.onreadystatechange = WebForm_CallbackComplete;
40
callback.xmlRequest = xmlRequest;
41
xmlRequest.open("POST", theForm.action, true);
42
xmlRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
43
xmlRequest.send(postData);
44
return;
45
}
46
callback.xmlRequest = new Object();
47
var callbackFrameID = "__CALLBACKFRAME" + callbackIndex;
48
var xmlRequestFrame = document.frames[callbackFrameID];
49
if (!xmlRequestFrame) {
50
xmlRequestFrame = document.createElement("IFRAME");
51
xmlRequestFrame.width = "1";
52
xmlRequestFrame.height = "1";
53
xmlRequestFrame.frameBorder = "0";
54
xmlRequestFrame.id = callbackFrameID;
55
xmlRequestFrame.name = callbackFrameID;
56
xmlRequestFrame.style.position = "absolute";
57
xmlRequestFrame.style.top = "-100px"
58
xmlRequestFrame.style.left = "-100px";
59
try {
60
if (callBackFrameUrl) {
61
xmlRequestFrame.src = callBackFrameUrl;
62
}
63
}
64
catch(e) {}
65
document.body.appendChild(xmlRequestFrame);
66
}
67
var interval = window.setInterval(function() {
68
xmlRequestFrame = document.frames[callbackFrameID];
69
if (xmlRequestFrame && xmlRequestFrame.document) {
70
window.clearInterval(interval);
71
xmlRequestFrame.document.write("");
72
xmlRequestFrame.document.close();
73
xmlRequestFrame.document.write('<html><body>' +
74
'<form method="post">' +
75
'<input type="hidden" name="__CALLBACKLOADSCRIPT" value="t">' +
76
'</form></body></html>');
77
xmlRequestFrame.document.close();
78
xmlRequestFrame.document.forms[0].action = theForm.action;
79
var count = __theFormPostCollection.length;
80
var element;
81
for (var i = 0; i < count; i++) {
82
element = __theFormPostCollection[i];
83
if (element) {
84
var fieldElement = xmlRequestFrame.document.createElement("INPUT");
85
fieldElement.type = "hidden";
86
fieldElement.name = element.name;
87
fieldElement.value = element.value;
88
xmlRequestFrame.document.forms[0].appendChild(fieldElement);
89
}
90
}
91
var callbackIdFieldElement = xmlRequestFrame.document.createElement("INPUT");
92
callbackIdFieldElement.type = "hidden";
93
callbackIdFieldElement.name = "__CALLBACKID";
94
callbackIdFieldElement.value = eventTarget;
95
xmlRequestFrame.document.forms[0].appendChild(callbackIdFieldElement);
96
var callbackParamFieldElement = xmlRequestFrame.document.createElement("INPUT");
97
callbackParamFieldElement.type = "hidden";
98
callbackParamFieldElement.name = "__CALLBACKPARAM";
99
callbackParamFieldElement.value = eventArgument;
100
xmlRequestFrame.document.forms[0].appendChild(callbackParamFieldElement);
101
if (theForm["__EVENTVALIDATION"]) {
102
var callbackValidationFieldElement = xmlRequestFrame.document.createElement("INPUT");
103
callbackValidationFieldElement.type = "hidden";
104
callbackValidationFieldElement.name = "__EVENTVALIDATION";
105
callbackValidationFieldElement.value = theForm["__EVENTVALIDATION"].value;
106
xmlRequestFrame.document.forms[0].appendChild(callbackValidationFieldElement);
107
}
108
var callbackIndexFieldElement = xmlRequestFrame.document.createElement("INPUT");
109
callbackIndexFieldElement.type = "hidden";
110
callbackIndexFieldElement.name = "__CALLBACKINDEX";
111
callbackIndexFieldElement.value = callbackIndex;
112
xmlRequestFrame.document.forms[0].appendChild(callbackIndexFieldElement);
113
xmlRequestFrame.document.forms[0].submit();
114
}
115
}, 10);
116
}
var __pendingCallbacks = new Array();2
var __synchronousCallBackIndex = -1;3
function WebForm_DoCallback(eventTarget, eventArgument, eventCallback, context, errorCallback, useAsync) {4
var postData = __theFormPostData +5
"__CALLBACKID=" + WebForm_EncodeCallback(eventTarget) +6
"&__CALLBACKPARAM=" + WebForm_EncodeCallback(eventArgument);7
if (theForm["__EVENTVALIDATION"]) {8
postData += "&__EVENTVALIDATION=" + WebForm_EncodeCallback(theForm["__EVENTVALIDATION"].value);9
}10
var xmlRequest,e;11
try {12
xmlRequest = new XMLHttpRequest();13
}14
catch(e) {15
try {16
xmlRequest = new ActiveXObject("Microsoft.XMLHTTP");17
}18
catch(e) {19
}20
}21
var setRequestHeaderMethodExists = true;22
try {23
setRequestHeaderMethodExists = (xmlRequest && xmlRequest.setRequestHeader);24
}25
catch(e) {}26
var callback = new Object();27
callback.eventCallback = eventCallback;28
callback.context = context;29
callback.errorCallback = errorCallback;30
callback.async = useAsync;31
var callbackIndex = WebForm_FillFirstAvailableSlot(__pendingCallbacks, callback);32
if (!useAsync) {33
if (__synchronousCallBackIndex != -1) {34
__pendingCallbacks[__synchronousCallBackIndex] = null;35
}36
__synchronousCallBackIndex = callbackIndex;37
}38
if (setRequestHeaderMethodExists) {39
xmlRequest.onreadystatechange = WebForm_CallbackComplete;40
callback.xmlRequest = xmlRequest;41
xmlRequest.open("POST", theForm.action, true);42
xmlRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");43
xmlRequest.send(postData);44
return;45
}46
callback.xmlRequest = new Object();47
var callbackFrameID = "__CALLBACKFRAME" + callbackIndex;48
var xmlRequestFrame = document.frames[callbackFrameID];49
if (!xmlRequestFrame) {50
xmlRequestFrame = document.createElement("IFRAME");51
xmlRequestFrame.width = "1";52
xmlRequestFrame.height = "1";53
xmlRequestFrame.frameBorder = "0";54
xmlRequestFrame.id = callbackFrameID;55
xmlRequestFrame.name = callbackFrameID;56
xmlRequestFrame.style.position = "absolute";57
xmlRequestFrame.style.top = "-100px"58
xmlRequestFrame.style.left = "-100px";59
try {60
if (callBackFrameUrl) {61
xmlRequestFrame.src = callBackFrameUrl;62
}63
}64
catch(e) {}65
document.body.appendChild(xmlRequestFrame);66
}67
var interval = window.setInterval(function() {68
xmlRequestFrame = document.frames[callbackFrameID];69
if (xmlRequestFrame && xmlRequestFrame.document) {70
window.clearInterval(interval);71
xmlRequestFrame.document.write("");72
xmlRequestFrame.document.close();73
xmlRequestFrame.document.write('<html><body>' + 74
'<form method="post">' + 75
'<input type="hidden" name="__CALLBACKLOADSCRIPT" value="t">' +76
'</form></body></html>');77
xmlRequestFrame.document.close();78
xmlRequestFrame.document.forms[0].action = theForm.action;79
var count = __theFormPostCollection.length;80
var element;81
for (var i = 0; i < count; i++) {82
element = __theFormPostCollection[i];83
if (element) {84
var fieldElement = xmlRequestFrame.document.createElement("INPUT");85
fieldElement.type = "hidden";86
fieldElement.name = element.name;87
fieldElement.value = element.value;88
xmlRequestFrame.document.forms[0].appendChild(fieldElement);89
}90
}91
var callbackIdFieldElement = xmlRequestFrame.document.createElement("INPUT");92
callbackIdFieldElement.type = "hidden";93
callbackIdFieldElement.name = "__CALLBACKID";94
callbackIdFieldElement.value = eventTarget;95
xmlRequestFrame.document.forms[0].appendChild(callbackIdFieldElement);96
var callbackParamFieldElement = xmlRequestFrame.document.createElement("INPUT");97
callbackParamFieldElement.type = "hidden";98
callbackParamFieldElement.name = "__CALLBACKPARAM";99
callbackParamFieldElement.value = eventArgument;100
xmlRequestFrame.document.forms[0].appendChild(callbackParamFieldElement);101
if (theForm["__EVENTVALIDATION"]) {102
var callbackValidationFieldElement = xmlRequestFrame.document.createElement("INPUT");103
callbackValidationFieldElement.type = "hidden";104
callbackValidationFieldElement.name = "__EVENTVALIDATION";105
callbackValidationFieldElement.value = theForm["__EVENTVALIDATION"].value;106
xmlRequestFrame.document.forms[0].appendChild(callbackValidationFieldElement);107
}108
var callbackIndexFieldElement = xmlRequestFrame.document.createElement("INPUT");109
callbackIndexFieldElement.type = "hidden";110
callbackIndexFieldElement.name = "__CALLBACKINDEX";111
callbackIndexFieldElement.value = callbackIndex;112
xmlRequestFrame.document.forms[0].appendChild(callbackIndexFieldElement);113
xmlRequestFrame.document.forms[0].submit();114
}115
}, 10);116
}
这个代码着实有些长了,但是仔细观察4--44行,有些AJAX基础的人马上就能识别出这是使用XmlHttpRequest进行发送请求的,callback函数也设置为我们在page_load函数中设置为getTime。当服务器完成响应后,会回调getTime函数,将服务器返回的时间字符串设置到文本框中。
本文提供了一个非常简单的ASP.NET无刷新页面的实现,利用了ASP.NET原本就有的函数,这也进一步说明AJAX不是一个新的东西。本文提供的方法当然可以扩展到更广泛的应用中,利用服务器返回的字符串(可以是普通的字符串,当然也可以为作用更大的xml和html片断)动态的改变页面的局部区域。


浙公网安备 33010602011771号