由于之前写的那个框架存在一些问题,博主对那个框架始终不太满意,经过一段时间的努力,将原来那个框架重新修改了一下,现在重新发布。
 
本次的代码中没有关于实现浏览器前进、后退按钮的处理,如果各位需要,可以从我原来的文章中获取相应的代码。地址在这里
 
声明:本文中的所有代码遵守GNU GPLv2的协议,对代码进行开源
 
发行注记:
2009/07/06
1、借鉴了Prototype中的相关内容,使程序更加面向对象
2、程序中集成了JSON数据支持
3、修正Internet Explorer、Firefox、Safari、Chrome、Opera等主流浏览器的兼容性
 
2009/06/22
1、取消很多不必要的参数
2、代码风格比较面向对象
3、允许用户对request请求方式进行设置(即用户可以选择同步或异步执行Ajax请求)
4、框架使用闭包封装
5、改进了程序的执行性能
 
JavaScript代码中提供了两个Demo函数,分别是使用同步、异步对同一个URL进行多次请求。
 
如果各位对这套框架有什么意见或建议,可以直接联系我,在代码的版权信息内,有本人的电子邮件地址
 
/*    
* Copyright © 2008 Nervous Studio, All rights reserved.    
*        
* LICENSE    
*        
* This program is free software; you can redistribute it and/or    
* modify it under the terms of the GNU General Public License (GPL)    
* as published by the Free Software Foundation; either version 2    
* of the License, or (at your option) any later version.    
*    
* This program is distributed in the hope that it will be useful,    
* but WITHOUT ANY WARRANTY; without even the implied warranty of    
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.        See the    
* GNU General Public License for more details.    
*        
* To read the license please visit [url]http://www.gnu.org/copyleft/gpl.html[/url]    
*        
*/

var Comment = {
  Version: "1.0.1",
    
  JSONFilter: /^\/\*-secure-\s*(.*)\s*\*\/\s*$/,
    
  Browser: {
    IE:         !!(window.attachEvent && !window.opera),  //  Internet Explorer 4+
    IE4:  (parseInt(navigator.appVersion) >= 4) ? true : false,  //  Internet Explorer Under Version 4
    Opera:    !!window.opera,    //  Opera Explorer
    WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,    //  Mozilla Firefox and Netscape
    Gecko:    navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1    //  Apple Safari and Google Chrome
  },
    
  Author: [
    {"Name":"Steven Wee", "EMail":"weimin0528@139.com", "MSN":"wmkm0113@Hotmail.com"}
  ]
}

var Class = {
  create: function() {
    return function() {
      this.initialize.apply(this, arguments);
    }
  }
};

//  Get Elements by input elementId
function $() {
  if ( arguments.length <= 0 ) {
    return null;
  } else {
    var returnElements = new Array();
    var argCount = arguments.length;
    for ( var i = 0 ; i < argCount ; i++ ) {
      var element = null;
      var elementId = arguments[i];
      if ( typeof elementId == 'string' ) {
        element = document.getElementById(elementId);
      }
      if ( element != null ) {
        returnElements.push(element);
      }
    }
    return returnElements;
  }
}

Object.extend = function(destination, source) {
  for (var property in source) {
    destination[property] = source[property];
  }
  return destination;
};

Object.extend(String.prototype, {
    
  parseJSON : function() {
    if ( typeof JSON !== 'undefined' ) {
      return JSON.parse(this);
    }
    
    if ( Comment.Browser.gecko ) {
      return new Function( "return" + this )();
    }
    
    return eval('(' + this + ')');
  },
    
  trim : function() {
    return this.replace(/(^\s*)|(\s*$)/g, "");
  }
});

Date.prototype.toJSON = function() {
    return '"' + this.getFullYear() + '-' +
        (this.getMonth() + 1).toPaddedString(2) + '-' +
        this.getDate().toPaddedString(2) + 'T' +
        this.getHours().toPaddedString(2) + ':' +
        this.getMinutes().toPaddedString(2) + ':' +
        this.getSeconds().toPaddedString(2) + '"';
};

var NervousAjax = Class.create();

NervousAjax.prototype = {
    
  _nsAjax : null,
    
  _request : null,
    
  activeRequestCount : 0,
    
  initialize : function() {
    _nsAjax = new NervousAjax.Request();
  },
    
  getActiveRequestCount : function() {
    return this.activeRequestCount;
  },
    
  switchPageAsync : function(url, elementId) {
    _nsAjax.getData(url, true, elementId);
  },
    
  switchPageSync : function(url, elementId) {
    _nsAjax.getData(url, false, elementId);
  },
    
  submitFormAsync : function(formId, elementId) {
    _nsAjax.submitForm(formId, true, elementId);
  },
    
  submitFormSync : function(formId, elementId) {
    _nsAjax.submitForm(formId, false, elementId);
  }
}

NervousAjax.Request = Class.create();

NervousAjax.Request.prototype = {
    
  _ajaxUtil : null,
    
  initialize : function() {
    _ajaxUtil = new NervousAjax.Util();
    _request = this._getRequest();
  },
    
  /*
  *  Get XMLHttpRequest object
  */

  _getRequest : function() {
    //  If XMLHttpRequest is a javascript object in the local
    if( window.XMLHttpRequest ) {
      return new XMLHttpRequest();
    } else if( window.ActiveXObject ){  //  Support the ActiveX
      try{
        //  Create XMLHttpRequest object by instance an ActiveXObject
        return new ActiveXObject("Microsoft.XMLHTTP");  //  higher than msxml3
      }catch(e){
        try{
          //  Create XMLHttpRequest object by instance an ActiveXObject
          return new ActiveXObject("Msxml2.XMLHTTP");  //  lower than msxml3
        }catch(e){
          return null;
        }
      }
    }
    return null;
  },
    
  _sendRequest : function( url, data, syncStatus, elementId ) {
    
    var method = null;
    
    if ( data != null ) {
      _request.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
      method = "POST";
    } else {
      method = "GET";
    }
    if ( syncStatus ) {
      if ( !Comment.Browser.IE4 ) {
        _request.onload = function() { _ajaxUtil.parseReturn(elementId) };
      } else {
        _request.onreadystatechange = function() { _ajaxUtil.parseReturn(elementId) };
      }
    }
    _request.open(method, url, syncStatus);
    _request.send(data);
  },
    
  submitForm : function(formId, syncStatus, elementId) {
    var formElement = $(formId)[0];
    var data = _ajaxUtil.encodeFormData(formElement);
    var actionURL = formElement.getAttributeNode("action").value;
    this._sendRequest(actionURL, data, syncStatus, elementId);
    if ( !syncStatus ) {
      _ajaxUtil.bindData(elementId);
    }
  },
    
  getData : function(url, syncStatus, elementId) {
    this._sendRequest(url, null, syncStatus, elementId);
    if ( !syncStatus ) {
      if ( elementId == null ) {
        _ajaxUtil.bindData();
      } else {
        _ajaxUtil.bindData(elementId);
      }
    }
  }
}

NervousAjax.Util = Class.create();

NervousAjax.Util.prototype = {
    
  initialize : function() {
    
  },
    
  _bindToElement : function( elementId, data ) {
    var element = $(elementId)[0];
    switch ( element.tagName.toLowerCase() ) {
    case "div":
    case "span":
    case "textarea":
      element.innerHTML = data;
      break;
    case "select":
      var childCount = element.childNodes.length;
      while ( childCount > 0 ) {
        //  Clear all values when the values is exists
        element.removeChild(elem.childNodes[0]);
        childCount--;
      }
      // Bind data    
      var itemCount = data.length;
      for ( var i = 0; i < itemCount; i++ ) {
        var option = document.createElement("OPTION");
        
        option.value = data[i].Value;
        option.text = data[i].Text;
        
        elem.options.add(option);
      }
      break;
    case "ul":
      // Bind data    
      var itemCount = data.length;
      for ( var i = 0; i < itemCount; i++ ) {
        var innerCode = "<li><a href=\"" + data[i].URL + "\" title=\"" + data[i].Title + "\">" + data[i].Value + "</a></li>";
        element.innerHTML += innerCode;
      }
      break;
      default:
        throw new SyntaxError('Element type error! Defined type:' + elementType + ', bind element type:' + element.tagName);
    }
  },
    
  parseReturn : function(elementId) {
    if ( Comment.Browser.IE || Comment.Browser.WebKit ) {
      if ( _request.readyState == 1 ) {
        NervousAjax.activeRequestCount++;
      } else if ( _request.readyState == 4 ) {
        NervousAjax.activeRequestCount--;
        //  Receive the request data finished
        if( _request.status == 200 ){
          //  Received data success
          if ( elementId == null ) {
            this.bindData();
          } else {
            this.bindData(elementId);
          }
        } else {
        //  Received data error
        alert("Not able to retrieve description " + _request.statusText);
        }
      }
    } else {
      if ( _request.readyState == 3 ) {
        NervousAjax.activeRequestCount++;
      } else if ( _request.readyState == 4 ) {
        NervousAjax.activeRequestCount--;
        //  Receive the request data finished
        if( _request.status == 200 ){
          //  Received data success
          if ( elementId == null ) {
            this.bindData();
          } else {
            this.bindData(elementId);
          }
        } else {
          //  Received data error
          alert("Not able to retrieve description " + _request.statusText);
        }
      }
    }
  },
    
  /*
    *  Analyze form elements data
    *  @param  formElement  FormObject
    */

  encodeFormData : function(formElement) {
    var whereClause = "";
    var and = "";
    var elementCount = formElement.length;
    for ( i = 0 ; i < elementCount ; i++ ) {
      var element = formElement[i];
      if ( element.name != "" ) {
        if (element.type=='select-one') {
          element_value = element.options[element.selectedIndex].value;
        } else if ( element.type == 'checkbox' || element.type == 'radio' ) {
          if ( element.checked == false ) {
            break;    
          }
          element_value = trim(element.value);
        } else {
          element_value = trim(element.value);
        }
        whereClause += and + trim(element.name) + '=' + element_value.replace(/\&/g,"%26");
        and = "&"
      }
    }
    return whereClause;
  },
    
  bindData : function() {
    var returnValue = _request.responseText;
    var elementId = null;
    var bindCount = null;
    if ( arguments.length == 0 ) {
      bindCount = returnJSON.length;
      var returnJSON = returnValue.parseJSON();
      for ( var i = 0 ; i < bindCount ; i++ ) {
        elementId = returnJSON[i].ElementId;
        this._bindToElement(elementId, returnJSON[i].Data);
      }
    } else {
      bindCount = arguments.length;
      for ( var i = 0 ; i < bindCount ; i++ ) {
        elementId = arguments[i];
        this._bindToElement(elementId, returnValue);
      }
    }
  }
}