发布: 2007-9-07 19:42 |
作者: admin |
来源:
博客网
在body快结束的时候还有一段这样的代码:
WebForm_InitCallback();好,这些应该就是asp.net为了实现客户端回调所作的补充工作了吧,咱们来研究吧。
首先看js资源文件(20多K,汗一个...)。先在资源文件里面找到这个方法,WebForm_InitCallback();
方法如下:
1function WebForm_InitCallback() {
2 var count = theForm.elements.length;
3 var element;
4 for (var i = 0; i < count; i++) {
5 element = theForm.elements[i];
6 var tagName = element.tagName.toLowerCase();
7 if (tagName == "input") {
8 var type = element.type;
9 if ((type == "text" type == "hidden" type == "password"
10 ((type == "checkbox" type == "radio") & element.checked)) &&
11 (element.id != "__EVENTVALIDATION")) {
12 WebForm_InitCallbackAddField(element.name, element.value);
13 }
14 }
15 else if (tagName == "select") {
16 var selectCount = element.options.length;
17 for (var j = 0; j < selectCount; j++) {
18 var selectChild = element.options[j];
19 if (selectChild.selected == true) {
20 WebForm_InitCallbackAddField(element.name, element.value);
21 }
22 }
23 }
24 else if (tagName == "textarea") {
25 WebForm_InitCallbackAddField(element.name, element.value);
26 }
27 }
28}这个方法就是把表单里面所有的值全部装载到一个键值对里面去。
附WebForm_InitCallbackAddField(element.name, element.value);方法实现:
function WebForm_InitCallbackAddField(name, value) {
var nameValue = new Object();
nameValue.name = name;
nameValue.value = value;
__theFormPostCollection[__theFormPostCollection.length] = nameValue;
__theFormPostData += name + "=" + WebForm_EncodeCallback(value) + "&";
}
function WebForm_EncodeCallback(parameter) {
if (encodeURIComponent) {
return encodeURIComponent(parameter);
}
else {
return escape(parameter);
}
}
那么就是asp.net在初始化客户端回调功能的时候,其实就是将表单里面的所有键值对全部装载到一个全局的键值对里面去了。
然后,咱们来看看unction CallServer(arg, context){ WebForm_DoCallback('__Page',arg,ReceiveServerData,context,null,false);}所作的工作。
在示例中,点击按钮,就触发了CallServer方法,
function LookUpStock()
{
var lb = document.getElementById("ListBox1");
var product = lb.options[lb.selectedIndex].text;
CallServer(product, "");
}
在资源文件中找到WebForm_DoCallback方法,由于方法太长太大,只有分段解析:
unction WebForm_DoCallback(eventTarget, eventArgument, eventCallback, context, errorCallback, useAsync) {
var postData = __theFormPostData +
"__CALLBACKID=" + WebForm_EncodeCallback(eventTarget) +
"&__CALLBACKPARAM=" + WebForm_EncodeCallback(eventArgument);
if (theForm["__EVENTVALIDATION"]) {
postData += "&__EVENTVALIDATION=" + WebForm_EncodeCallback(theForm["__EVENTVALIDATION"].value);
}
var xmlRequest,e;
try {
xmlRequest = new XMLHttpRequest();
}
catch(e) {
try {
xmlRequest = new ActiveXObject("Microsoft.XMLHTTP");
}
catch(e) {
}
}这段代码是将一些参数附加上去到postData变量上。并创建xmlRequest对象。不过这个创建异步对象方法似乎有点不妥,他是先看是否是非IE的浏览器,然后被cacth住了才创建ActiveX对象,也就是说在IE大行其道的时候不得不多次catch,为什么不把创建ActiveX对象放在前面节省资源呢?不管这么多,接下来看:
var setRequestHeaderMethodExists = true;
try {
setRequestHeaderMethodExists = (xmlRequest && xmlRequest.setRequestHeader);
}
catch(e) {}
var callback = new Object();
callback.eventCallback = eventCallback;
callback.context = context;
callback.errorCallback = errorCallback;
callback.async = useAsync;
var callbackIndex = WebForm_FillFirstAvailableSlot(__pendingCallbacks, callback);
if (!useAsync) {
if (__synchronousCallBackIndex != -1) {
__pendingCallbacks[__synchronousCallBackIndex] = null;
}
__synchronousCallBackIndex = callbackIndex;
}
if (setRequestHeaderMethodExists) {
xmlRequest.onreadystatechange = WebForm_CallbackComplete;
callback.xmlRequest = xmlRequest;
xmlRequest.open("POST", theForm.action, true);
xmlRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xmlRequest.send(postData);
return;
}这几段语句最重要的是将异步回调方法赋值为:WebForm_CallbackComplete。
不过俺们还忽略了一些细节,让我们从头再来。上面有一段代码
if (setRequestHeaderMethodExists)
也就是说在setRequestHeaderMethodExists这个变量不为null的时候才能够发送异步对象,那么这个变量是怎么定义的呢??
var setRequestHeaderMethodExists = true;
try {
setRequestHeaderMethodExists = (xmlRequest && xmlRequest.setRequestHeader);
}也就是说只有当正确的创建了xmlRequest对象后才能够使用ajax,那么如果不能够正确创建ajax对象怎么办呢?接着看代码!
callback.xmlRequest = new Object();
var callbackFrameID = "__CALLBACKFRAME" + callbackIndex;
var xmlRequestFrame = document.frames[callbackFrameID];
if (!xmlRequestFrame) {
xmlRequestFrame = document.createElement("IFRAME");
xmlRequestFrame.width = "1";
xmlRequestFrame.height = "1";
xmlRequestFrame.frameBorder = "0";
xmlRequestFrame.id = callbackFrameID;
xmlRequestFrame.name = callbackFrameID;
xmlRequestFrame.style.position = "absolute";
xmlRequestFrame.style.top = "-100px"
xmlRequestFrame.style.left = "-100px";
try {
if (callBackFrameUrl) {
xmlRequestFrame.src = callBackFrameUrl;
}
}
catch(e) {}
document.body.appendChild(xmlRequestFrame);
}接下来原来是创建一个iframe!呵呵,原来是保证所有的浏览器都能使用ajax才出的这招。
再下来应该就是给这个iframe里面加载一些变量了,并且提交这个iframe了:
var interval = window.setInterval(function() {
xmlRequestFrame = document.frames[callbackFrameID];
if (xmlRequestFrame && xmlRequestFrame.document) {
window.clearInterval(interval);
xmlRequestFrame.document.write("");
xmlRequestFrame.document.close();
xmlRequestFrame.document.write('
热门推荐: | 最能提升工作效率的200个热键 | 细数Windows操作系统的20条鸡肋 |
【责任编辑 彭凡】
文章来源于领测软件测试网 https://www.ltesting.net/