追求艺术的脚步
Be the change you want to see in the world.Things are always as hard as you think but always as easy as you do.

        近来忙毕业设计,又很长时间没写blog了。
        学ajax也有段时间了,理论是看了不少,也对MagicAjax框架做了下了解,当然要吃透它还是有很长的路要走。
        一直觉得对Ajax底层的代码应该总结一下。其实很底层的代码是比较简洁明了的,但功能却比较简单。一般我们都用Send(null).以前我一直在想我怎么来控制当异步传送Http请求时要调用的后台的指定的(我想用的)代码,现在终于明白了(唉,对自己的智商表示怀疑),那就要在Send方法中传送参数。参数中应该包括事件的触发者和它的参数,还有就是ViewState的值。
        具体代码如下(里面我加了些注释,后面不再解释):

  1__PageForm = null;
  2
  3function AjaxCallObject()
  4{
  5    this.Init();
  6}

  7
  8AjaxCallObject.prototype.Init = function()
  9{
 10    this.XmlHttp = this.GetHttpObject();
 11}

 12 
 13AjaxCallObject.prototype.GetHttpObject = function()
 14
 15    var xmlhttp;
 16    if (!xmlhttp) 
 17    {
 18        try 
 19        {
 20            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
 21        }
 
 22        catch (e) 
 23        {
 24            xmlhttp = false;
 25        }

 26    }

 27    return xmlhttp;
 28}

 29
 30AjaxCallObject.prototype.HookAjaxCall = function()
 31{
 32    __PageForm = document.getElementById('Form1');
 33    if (typeof __doPostBack != 'undefined')
 34        __doPostBack = this.DoPostBack;
 35}

 36
 37// Replaces normal __doPostBack
 38AjaxCallObject.prototype.DoPostBack = function(eventTarget, eventArgument)
 39{    
 40    AJAXCbo.DoAjaxCall(eventTarget, eventArgument);
 41}

 42 
 43AjaxCallObject.prototype.DoAjaxCall = function(eventTarget, eventArgument)
 44{
 45    var theData = '';
 46    var theform = __PageForm;
 47    
 48    if(theform == null)
 49    {
 50        return;
 51    }

 52    
 53    var thePage = theform.action;//得到页面地址
 54    var eName = '';
 55
 56    theData  = '__EVENTTARGET='  + this.EncodePostData(eventTarget.split("$").join(":")) + '&';//得到事件的发起者,也就是object Sender
 57    theData += '__EVENTARGUMENT=+ this.EncodePostData(eventArgument) + '&';//得到参数,就是EventArgs e
 58
 59    var elemCount = theform.elements.length;
 60    forvar i=0; i<elemCount; i++ )
 61    {
 62        curElem = theform.elements[i];
 63        eName = curElem.name;
 64        if( eName && eName != '' && curElem.tagName != "EMBED")
 65        {
 66            if( eName == '__EVENTTARGET' || eName == '__EVENTARGUMENT' )
 67            {}
 68            else
 69            {
 70                var type = curElem.type;
 71                var val = curElem.value;
 72
 73                if ( type == "submit" || type == "button" )
 74                    continue;
 75
 76                val = this.EncodePostData(val);
 77
 78                if ( type == "select-multiple" || type == "select-one" )
 79                {
 80                    var selectLength = curElem.options.length;
 81                    var optNameStr = this.EncodePostData(eName);
 82                    for (var j=0; j < selectLength; j++)
 83                        if (curElem.options[j].selected)
 84                            theData = theData + optNameStr + '=+ this.EncodePostData(curElem.options[j].value) + '&';
 85                }

 86                else if ( (type != "checkbox" && type != "radio"|| curElem.checked )
 87                {
 88                    theData = theData + this.EncodePostData(eName) + '=+ val + '&';
 89                }

 90            }

 91        }

 92    }

 93  
 94    if (theData.substr(theData.length-1== "&")
 95        theData = theData.substr(0, theData.length-1);
 96        //alert(theData);
 97        
 98    ifthis.XmlHttp )
 99    {        
100         //注释的是旧的代码,有问题,回送回来的状态都是0,原因还不明
101        /*AJAXCbo = new AjaxCallObject();
102
103        if( this.XmlHttp.readyState == 4 || this.XmlHttp.readyState == 0 )
104        {
105            // Asynchronous
106            this.XmlHttp.open("POST", thePage, true);
107            this.XmlHttp.onreadystatechange = function(){ AJAXCbo.ReadyStateChange(); };
108            this.XmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
109            this.XmlHttp.send(theData);
110        }*/

111        var oThis = this;
112        AJAXCbo = new AjaxCallObject();
113
114        ifthis.XmlHttp.readyState == 4 || this.XmlHttp.readyState == 0 )
115        {
116            ajaxCallType = "async";
117        
118            if ( ! ajaxCallType || ajaxCallType.toLowerCase() != "sync")
119            {
120                // 异步传输
121                this.XmlHttp.open("POST", thePage, true);
122                this.XmlHttp.onreadystatechange = function(){ oThis.ReadyStateChange(); };
123                this.XmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
124                this.XmlHttp.send(theData);
125            }

126            else
127            {
128                // 同步传输,页面会刷新
129                window.setTimeout(
130                    function()
131                    {
132                        oThis.XmlHttp.open("POST", thePage, false);
133                        oThis.XmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
134                        oThis.XmlHttp.send(theData);
135
136                        if( oThis.XmlHttp.status == 200 && oThis.XmlHttp.statusText == "OK" )
137                            oThis.OnComplete(oThis.XmlHttp.responseText, oThis.XmlHttp.responseXML);
138                        else
139                            oThis.OnError(oThis.XmlHttp.status, oThis.XmlHttp.statusText, oThis.XmlHttp.responseText);
140                    }
1);
141            }
            
142        }

143    }

144    return true;
145}

146
147/*AjaxCallObject.prototype.OnLoading = function()
148{
149  // Loading
150}
151
152AjaxCallObject.prototype.OnLoaded = function()
153{
154  // Loaded
155}
156
157AjaxCallObject.prototype.OnInteractive = function()
158{
159  // Interactive
160}
161*/

162AjaxCallObject.prototype.OnComplete = function(responseText, responseXml)
163{
164    this.SetHtmlOfPage(responseText);
165    return true;
166}

167
168/*AjaxCallObject.prototype.OnAbort = function()
169{}*/

170
171AjaxCallObject.prototype.OnError = function(status, statusText, responseText)
172{
173    if (status==200)
174    {
175        // a weird bug of Opera sometimes invokes OnError when there's no error
176        this.OnComplete(responseText);
177        return;
178    }

179
180    document.close();    // for IE
181    document.write(responseText);
182    document.close();    // for Firefox
183}

184
185AjaxCallObject.prototype.ReadyStateChange = function()
186{
187    /*if( this.XmlHttp.readyState == 1 )
188    {
189        this.OnLoading();
190    }
191    else if( this.XmlHttp.readyState == 2 )
192    {
193        this.OnLoaded();
194    }
195    else if( this.XmlHttp.readyState == 3 )
196    {
197        this.OnInteractive();
198    }
199    else */

200    //alert("ly");
201    //alert(this.XmlHttp.readyState);
202    ifthis.XmlHttp.readyState == 4)
203    {
204        /*if( this.XmlHttp.status == 0 )
205            this.OnAbort();
206        else*/

207        ifthis.XmlHttp.status == 200 )
208        {
209            this.OnComplete(this.XmlHttp.responseText, this.XmlHttp.responseXML);
210        }

211        else
212        {
213            this.OnError(this.XmlHttp.status, this.XmlHttp.statusText, this.XmlHttp.responseText);   
214        }

215    }

216}

217
218AjaxCallObject.prototype.EncodePostData = function(data)
219{
220    return data.split("%").join("%25").split("=").join("%3d").split("&").join("%26").split("+").join("%2b");
221}

222
223AjaxCallObject.prototype.SetHtmlOfPage = function(html)
224{
225    document.close();    // for IE
226    document.write(html);//用新的html代码替代页面上的html代码
227    document.close();    // for Firefox
228}

229
230var AJAXCbo = new AjaxCallObject();
        代码长了点,不过可以直接用了,只要在相应的后台代码中给服务器控件加段代码就成了。比如说,Web页面上放了个按钮控件,ID为Button1,那么在后台代码的Page_Load中加上下面一段代码:
Button1.Attributes.Add("onclick","modify();");
这里的modify是我在页面的html里定义的一个方法,其内容是:
<script>
            
function modify()
            
{
                
if(typeof(AJAXCbo) == 'undefined')
                
{
                    
var AJAXCbo = new AjaxCallObject();
                }

                AJAXCbo.HookAjaxCall();
            }

        
</script>
         到这就结束了,你可以看到无刷新更新的效果了。接下来的工作就是想办法更进一步,只把更新过的值传到相应的控件,该怎么做还需要继续努力了,呵呵。
        水平有限,难免有错误,望能和大家多多交流!
 例子代码下载:/Files/fxb248/ajaxtestaaa.rar
posted on 2006-05-25 11:42  小笨笨  阅读(1208)  评论(2编辑  收藏  举报