`
44424742
  • 浏览: 232512 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
文章分类
社区版块
存档分类
最新评论
阅读更多
最近由于项目需要,专心研究了一下Ajax的相关程序设计,本来一开始想用Prototype或者jQuery等框架,后来发现其实用不到这些框架里面的那么多内容,强行使用的话只能拖累我网站的访问者,降低用户体验,因此决定自己写一套适合自己需求的Ajax代码库。
在这套Ajax代码库中,实现了如下的功能:
1、Ajax远程调用数据
2、通过Ajax异步提交Form表单
3、返回数据后,能够将数据绑定到页面的相关控件内(如:div、select、ul、span等等)
4、让Ajax程序支持浏览器的前进、后退按钮
一、什么是Ajax,他都能做什么?
AJAX全称为“Asynchronous JavaScript and XML”(非同步JavaScript和XML),是一种创建互动式网页应用的网页开发技术。
使用Ajax的最大优点,就是能在不更新整个页面的前提下维护数据。这使得Web应用程序更为迅捷地回应用户动作,并避免了在网络上发送那些没有改变过的信息。
Ajax不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。就像DHTML应用程序那样,Ajax应用程序必须在众多 不同的浏览器和平台上经过严格的测试。随着Ajax的成熟,一些简化Ajax使用方法的程序库也相继问世。同样,也出现了另一种辅助程序设计的技术,为那 些不支持JavaScript的用户提供替代功能。
二、核心代码
所谓核心代码就是提供一个能够跨浏览器的Ajax调用代码,这部分代码是后面扩展代码的必备部分,在这部分代码中我们提供了一个创建XMLHttpRequest对象并能够与Web服务器进行异步数据交换。
在我写的这些代码中,自定义了两个相关的函数,一个是通用的获取HTML对象函数,还有一个就是自动过滤字符串开头结尾的空格,代码如下:
function $( elementId ) {
return document.getElementById(elementId);
}

function trim(str){//删除左右两端的空格
return str.replace(/(^\s*)|(\s*$)/g, "");
}
Ajax的核心代码如下:
/*
*根据不同的浏览器,获取Ajax对象
*/

function getAjaxObject() {
var xmlHttpRequest;
//判断是否把XMLHttpRequest实现为一个本地javascript对象
if(window.XMLHttpRequest){
xmlHttpRequest = new XMLHttpRequest();
}else if(window.ActiveXObject){//判断是否支持ActiveX控件
try{
//通过实例化ActiveXObject的一个新实例来创建XMLHttpRequest对象
xmlHttpRequest = new ActiveXObject("Microsoft.XMLHTTP");//msxml3以上版本
}catch(e){
try{
//通过实例化ActiveXObject的一个新实例来创建XMLHttpRequest对象
xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP");//msxml3以下版本
}catch(e){}
}
}
if ( !xmlHttpRequest ) {
alert("创建Ajax对象失败,您将无法正常浏览网页");
}
return xmlHttpRequest;
}
/*
*异步方式提交请求
*/

function sendRequestByAjax(method, url, data, dataHandler) {
//获取Ajax对象
request = getAjaxObject();
//设置回调函数
if( !IE4 ){
request.onload = dataHandler;
} else {
request.onreadystatechange = dataHandler;
}
request.open(method, url, true);//true代表使用异步方式 false代表使用同步方式
//处理提交方式
if ( "get" == method.toLowerCase() ) {
//使用GET方式提交数据
var urls = url.split("?");
if ( urls[1] == "" || typeof(urls[1]) == "undefined" ) {
url = urls[0] + "?" + data;
} else {
url = urls[0] + "?" + urls[1] + "&" + data;
}
data = null;// for GET method,request必须为空

} else if ( "post" == method.toLowerCase() ){
//使用POST方式提交数据
request.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
}
request.send(data);
}
三、回调函数以及数据解析
根据Ajax提出者Jesse James Garrett建议,Ajax使用XHTML+CSS来表示信息,使用JavaScript操作DOM(Document Object Model)进行动态显示及交互,使用XML和XSLT进行数据交换及相关操作,由于Opera浏览器不支持XSLT格式对象,也不支持XSLT,所以现 在一般情况下都是使用XML进行数据传递。
在回调函数中,会出现request的一些相关属性,其代表值如下:
readyState:提供当前 HTML 的就绪状态。
0:请求未初始化
1:请求已经建立,但是还没有发送(还没有调用 send())
2:请求已发送,正在处理中(通常现在可以从响应中获取内容头)
3:请求在处理中,通常响应中已有部分数据可用了
4:响应已完成
status:提供当前HTML的状态码
401:未经授权
403:禁止访问
404:没找到访问页
200:正常
回调函数如下所示:
/*
*返回数据格式为XML的回调函数
*/

function xmlCallBack() {
//数据接收完成
if( request.readyState == 4 ){
//数据正常接收
if( request.status == 200 ){
//调用XML文件解析函数
parseXMLMessage();
} else {
//显示错误信息
alert("Not able to retrieve description"+request.statusText);
}
}
}
/*
*XML文件解析函数
*/

function parseXMLMessage() {
//获取返回的XML文件
var xmlDoc=request.responseXML.documentElement;
//解析XML文件
parseXML("elementId", xmlDoc);
}
/*
*解析XML文件
*@paramelementId要将数据绑定的对象Id
*@paramxmlDoc要解析的XML文件
*/

function parseXML(elementId, xmlDoc) {
//这里XML文件的格式根据你的自定义,自行修改
var xmlRoot = xmlDoc.getElementsByTagName("items");
var dataType = xmlRoot[0].getAttribute("dataType");
var items = xmlDoc.getElementsByTagName('item');
switch ( dataType.toLowerCase() ) {
case "array" :
//返回对象为结果集
bindItems(elementId, items);
break;
case "string" :
//返回对象为字符串
bindText(elementId, items[0].childNodes[0].firstChild.nodeValue);
}
}
如果Ajax调用后返回的是一个HTML页面,则可以使用下面的这个回调函数:
/*
*HTML文件解析函数
*/

function htmlCallBack() {
if( request.readyState == 4 ){
if( request.status == 200 ){
parseHTMLMessage();
} else {
alert("Not able to retrieve description"+request.statusText);
}
}
}
/*
*解析HTML文件
*/

function parseHTMLMessage() {
//获取返回的HTML代码
var htmlCode = request.responseText;
//绑定HTML代码
bindText("elementId", htmlCode);
}
四、数据绑定
数据绑定根据不同的控件类型,可以使用以下两个数据绑定函数,能够实现绑定select控件、ul无序列表、插入HTML代码等:
/*
*绑定结果集
*/

function bindItems(elementId, items) {
var elem = $(elementId);
//判断要绑定的对象,类型是否匹配
if ( elem.tagName.toLowerCase() != "select" && elem.tagName.toLowerCase() != "ul" ) {
alert("数据类型不匹配,无法进行数据绑定");
return;
}
//绑定select
if ( elem.tagName.toLowerCase() == "select" ) {
while ( elem.childNodes.length > 0 ) {
//清除现有数据
elem.removeChild(elem.childNodes[0]);
}
// 绑定数据
for ( var i = 0; i < items.length; i++ ) {
var option = document.createElement("OPTION");
var Data = items[i];

option.value = Data.childNodes[0].firstChild.nodeValue;
option.text = Data.childNodes[1].firstChild.nodeValue;

elem.options.add(option);
}
} else if ( elem.tagName.toLowerCase() == "ul" ) {
//绑定ul列表
elem.innerHTML = "";
// bind data
for ( var i = 0; i < items.length; i++ ) {
var Data = items[i];
var urlAddress = Data.childNodes[0].firstChild.nodeValue;
var showText = Data.childNodes[1].firstChild.nodeValue;
var innerCode = "<li><a href=\"" + urlAddress + "\" title=\"" + showText + "\">" + showText + "</a></li>";
elem.innerHTML += innerCode;
}
}
}
/*
*绑定字符串,也可以实现绑定HTML代码
*/

function bindText(elementId, value) {
var elem = $(elementId);
//分析绑定对象类型
switch ( elem.tagName.toLowerCase() ) {
case "div":
case "span":
case "textarea":
elem.innerHTML = value;
break;
case "input":
elem.value = value;
break;
default:
alert("数据类型不匹配,无法进行数据绑定");
return;
}
saveHistory(elementId); //保存历史记录用于实现浏览器的前进、后退按钮
}
五、进阶功能——实现Ajax提交Form表单
通过Ajax提交Form有以下两个非常重要的地方:
1、需要解析所有Form中的控件,将控件拼成类似于“?param1=value1&param2=value2......”这样的字符串,然后通过“POST”模式异步提交,将上面拼成的字符串通过request.send(data)发送到服务器。
2、关于文件上传,由于我没有这方面的需求,没有写出一个测试后的代码,但通过查阅相关资料,看到可以通过隐藏IFrame来实现这一功能。
通过Ajax异步提交表单的代码如下:
/*
*通过Ajax异步提交表单
*/

function submitFormByAjax(formId) {
sendRequestByAjax($(formId).method, $(formId).getAttributeNode("action").value, encodeFormData($(formId)), htmlCallBack);
}
解析Form内控件,并拼成字符串的函数如下:
/*
*分析Form表单数据
*@paramformElementForm对象
*/

function encodeFormData(formElement) {
var whereClause = "";
var and = "";
for ( i = 0 ; i < formElement.length ; 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;
}
六、进阶功能——实现浏览器的前进、后退按钮
很多人在使用了Ajax技术后会发现,浏览器的前进、后退按钮无效了,大大降低了用户体验,曾经这一点也被作为Ajax技 术的弊端而大范围讨论,后来经过不断的尝试,终于实现了这一功能,听起来很简答,就是通过一个隐藏的IFrame,使用JavaScript改变 IFrame的src属性而激活浏览器的前进、后退按钮。再通过一个特殊的JavaScript函数,实现更新页面数据。
具体的代码如下:
var historyValue = new Array(10); //保存记录的最大次数
var historyCount = 0;

/*
*保存历史记录
*@paramelementId要保存的区域ID
*/

function saveHistory(elementId) {
//"historyFrame"隐藏的IFrame的ID属性值
var iframeDocument = $("historyFrame");
if ( iframeDocument != null ) {
if ( historyCount == 9 ) {
historyCount = 0;
} else {
historyCount++;
}
historyValue[historyCount] = new Array(2);
historyValue[historyCount][0] = elementId;
var element = $(elementId);
historyValue[historyCount][1] = element.innerHTML;
iframeDocument.src = "/history.jsp?" + historyCount;
}
}
/*
*获取历史记录
*@paramhistoryIndex历史记录索引号
*/

function getHistory(historyIndex) {
if ( historyIndex != historyCount ) {
if ( historyValue[historyIndex] ) {
historyCount = historyIndex;
}
var element = $(historyValue[historyCount][0]);
element.innerHTML = historyValue[historyCount][1];
}
}
history.jsp页面中的代码很简单,只有以下代码:
<script>
var url=window.location.href;
if(url.indexOf('?')>-1)
{
parent.getHistory(url.substr(url.indexOf('?')+1));
document.write(window.location.search.substr(1));
}

</script>
在页面最下端记得写上下面的代码:
<iframe id="historyFrame" name="historyFrame" src="/history.jsp?0" height="0px" frameborder="no"></iframe>
七、总结
我认为Ajax的应用最好根据自己的需求,来实现相应的功能,尽量避免JavaScript代码过多,拖累客户端浏览器。 由于JavaScript代码设计过于灵活,如果JavaScript程序员水平相当,肯定能够开发出很好的JavaScript程序,如果 JavaScript程序员水平良莠不齐,最好避免多人同时开发一套JavaScript程序,防止JavaScript代码质量降低。
由于JavaScript调试起来非常不方便,建议大家多多使用FireFox浏览器的错误控制台,会给大家提供很多的方便。
分享到:
评论

相关推荐

    计算机视觉开发:OpenCV入门教程及应用

    内容概要:本文档详细介绍了OpenCV的基本概念及其在计算机视觉领域的应用,重点讲解了OpenCV在C++和Python环境下的安装方法,并提供了图像读取、显示、基本操作、视频处理以及面部检测的具体代码示例。此外,还涉及了一些图像处理技术的快速演示和进一步学习的路径建议。 适合人群:对计算机视觉感兴趣的新手开发者和技术爱好者。 使用场景及目标:本教程适用于希望入门计算机视觉和图像处理的新手,通过实际操作练习提升技术水平,掌握OpenCV的基本用法,并能够应用于实际项目,如OCR应用、图像分割与目标检测等。 阅读建议:建议读者按照文档提供的步骤进行实践,逐步完成每个代码示例,结合官方文档和其他资源深入理解各个函数的作用。对于初学者来说,可以通过多动手尝试,加深对OpenCV的理解。

    围绕着一系列的经典Python练习题 .zip

    围绕着一系列的经典Python练习题。Python练习一些按照回顾排列的Python练习题。欢迎提交你的答案或添加更多有趣的题目!从开始学Python以来,接触了精彩的练习题。下面十个练习题,是我做的和练习出来的题里比较有趣的,现在按照难度由低到高排列。欢迎到GitHub上提交你的答案。猜测数字经典的猜数字游戏,几乎是学编程时都会做的。功能描述随机选择三个以内的数字作为答案。用户输入一个数字,程序会提示大了或者小了,直到用户猜中。2.FizzBu​​zz另一道经典编程题。功能描述遍历并打印0到100,如果数字能被3整除,显示Fizz如果数字能被5整除,显示Buzz如果能同时被3和5整除,就显示FizzBu​​zz。结果应该类似0,1 ,2,嘶嘶声,4,嗡嗡声,6……14,嘶嘶声,16……3. 猜测数字的AI和猜数字一样,不过这次是设计一个能猜数字的人工智能功能描述用户输入一个单位以内的数字,AI需要最少的猜测次数,并显示出猜测的次数和数字。4.整点报时老式的挂钟会在整点报时,响铃的次数和时间是一致的。我们设计了一个在电脑上运行的报时

    毕设源码-python-django基于python技术的学生管理系统的设计与开发-期末大作业+说明文档.rar

    本项目是一个基于Python技术的学生管理系统,采用Django框架进行开发,旨在为计算机相关专业的学生提供一个实践性强、功能全面的管理系统,以帮助他们完成毕业设计或进行项目实战练习。 系统实现了对学生信息、课程信息、成绩、考勤等多方面的管理功能。学生信息管理包括学生基本信息的增删改查;课程信息管理允许管理员设置课程信息,包括课程名称、授课老师、学分等;成绩管理功能使学生和教师能够录入、查看和修改成绩;考勤管理则方便教师记录学生的出勤情况。 该项目采用B/S架构,前端使用HTML、CSS、JavaScript等技术,后端使用Python语言和Django框架,数据库采用MySQL。Django框架提供了强大的后台管理功能,使得系统管理更加便捷。 通过开发这个项目,学生不仅能提升自己的编程能力,还能学习到如何构建一个实际应用的系统,对于即将步入职场的学生来说,具有很高的实用价值。

    python入门-安装Python软件包.pdf

    python入门——安装Python软件包

    消息中间件源码学习(打注释学习).zip

    消息中间件源码学习(打注释学习)

    阿里消息中间件MetaQ学习Demo.zip

    阿里消息中间件MetaQ学习Demo

    数学建模培训资料 数学建模实战题目真题答案解析解题过程&论文报告 抑制房地产泡沫问题研究 共69页.pdf

    数学建模培训资料 数学建模实战题目真题答案解析解题过程&论文报告 抑制房地产泡沫问题研究 共69页.pdf

    rbac组件(基于角色的权限控制).zip

    rbac组件(基于角色的权限控制)

    Discuz! X3.5 R20240520 增量补丁包下载 X3.5 2023-12-21 升级到 X3.5 2024-05-20 补丁包

    压缩包内,SC是简体补丁包,TC是繁体补丁包

    ssm框架Java项目源码-基于Java的在线日语培训平台的设计与实现+jsp毕设-大作业.zip

    本项目是一个基于Java的在线日语培训平台的设计与实现,采用SSM框架(Spring+SpringMVC+MyBatis)进行开发,旨在为计算机相关专业的学生提供一个实践和学习的平台,同时也为日语学习者提供一个在线学习的空间。项目中主要功能涵盖了用户管理、课程管理、学习资源上传下载、在线测试与反馈等多个方面。通过该平台,教师能够轻松管理课程内容和学生信息,学生则可以随时随地访问学习资源,参与在线课程和测试,从而提高学习效率和兴趣。 在开发此项目的过程中,我们重点关注了系统的可维护性和可扩展性,确保代码结构清晰,便于后续的功能迭代和优化。此外,通过使用SSM框架,实现了前后端的分离,提高了开发效率和系统的响应速度。该项目不仅能够满足毕设的需求,还能作为Java学习者提升编程能力和实践经验的实用工具。

    机器xuex(大模型):语言模型在生成问题答案时的真实性数据集

    TruthfulQA是一个专门设计的基准测试数据集,用于衡量。这个数据集包含了817个问题,覆盖了38个不同的类别,如健康、法律、金融和政治等。这些问题被精心设计,以至于某些人可能会因为错误的信念或误解而给出错误的答案。因此,要在这个数据集上表现良好,语言模型必须避免生成从模仿人类文本中学到的错误答案。 TruthfulQA的数据集结构包括两种配置:generation和multiple_choice。在generation配置中,每个问题都包含了类型、类别、问题、最佳答案、正确答案列表、错误答案列表和来源。而在multiple_choice配置中,每个问题都提供了四个选项,模型需要从中选择正确的答案。 这个数据集的目的是为了测试语言模型在真实性方面的弱点,而不是测试模型在有用任务上的表现。研究发现,最大的模型通常是最不真实的,这与其他NLP任务不同,在其他任务中,模型的性能随着模型大小的增加而提高。TruthfulQA的数据集提供了一个重要的工具,用于评估和改进语言模型在生成真实和可靠信息方面的能力。

    多彩吉安红色旅游网站-JAVA-基于springBoot多彩吉安红色旅游网站的设计与实现

    多彩吉安红色旅游网站-JAVA-基于springBoot多彩吉安红色旅游网站的设计与实现

    基于servlet+jsp+mysql实现的影视管理系统课程设计

    【作品名称】:基于servlet+jsp+mysql实现的影视管理系统【课程设计】 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【项目介绍】: 基于servlet+jsp+mysql实现的影视管理系统【课程设计】 基于servlet+jsp+mysql实现的影视管理系统【课程设计】 Java Web课程设计,基于servlet+jsp+ajax+mysql做的影视管理系统 运行环境: Tomcat 9.0 JDK 1.8 MySQL 8.0 后台管理账号密码均为:root,项目依赖:lib 目录 【资源声明】:本资源作为“参考资料”而不是“定制需求”,代码只能作为参考,不能完全复制照搬。需要有一定的基础看懂代码,自行调试代码并解决报错,能自行添加功能修改代码。

    渗透测试人员的 Python 工具.zip

    渗透测试人员的 Python 工具渗透测试人员的 Python 工具如果你参与漏洞研究、逆向工程或渗透测试,我建议尝试 Python编程语言。它有一套丰富的有用库和程序。本页列出了其中一些。列出的大多数工具都是用 Python 编写的,其他工具只是现有 C 库的 Python 绑定,即它们使这些库可轻松地在 Python 程序中使用。一些更激进的工具(渗透测试框架、蓝牙粉碎器、Web 应用程序漏洞扫描器、战争拨号器等)被排除在外,因为这些工具在德国的法律地位仍然不太明确——即使在最高法院作出裁决之后也是如此。这个列表显然是为了帮助白帽黑客,目前我更愿意谨慎行事。网络Scapy发送、嗅探、剖析和伪造网络数据包。可交互使用或作为库使用pypcap、 Pcapy和 pylibpcaplibpcap 的几种不同的 Python 绑定libdnet低级网络例程,包括接口查找和以太网帧传输dpkt快速、简单的数据包创建/解析,包含基本 TCP/IP 协议的定义Impacket制作和解码网络数据包。包括对 NMB 和 SMB 等高级协议的支持pynidslibnids

    quark(夸克)正版下载

    quark(夸克)正版下载

    ssm框架Java项目源码-企业员工岗前培训管理系统+vue毕设-大作业.zip

    ssm框架Java项目源码-企业员工岗前培训管理系统+vue毕设-大作业.zip是一个专为计算机相关专业学生和Java学习者设计的项目资源。该项目以企业员工岗前培训管理为背景,采用经典的SSM(Spring+SpringMVC+MyBatis)框架进行后端开发,确保系统的稳定性和可扩展性。同时,前端采用Vue.js框架,实现了前后端分离,提升了用户体验和开发效率。 该项目的主要功能包括员工信息管理、培训课程管理、培训进度跟踪、考试成绩记录与统计等。通过这些功能,系统能够帮助企业高效地管理员工的岗前培训过程,确保培训质量,提升员工技能水平。 此外,该项目不仅适合作为计算机专业学生的毕业设计题目,也适合Java学习者进行项目实战练习,通过实际操作,加深对SSM框架和Vue.js的理解,提升编程能力和解决问题的能力。

    汇聚【Python应用】【Python实训】【Python技术分享】等等.zip

    你是 Pythonista汇聚【从零单排】【实战项目】【数据科学】【自然语言处理】【计算机】【面试题系列】【大航海】【Python应用】【错题集】【技术沙龙】【内推渠道】 】等等【人人都是Pythonista】由公众号【Python专栏】推出,请认准唯一标识请仔细阅读本文档,尤其是使用说明。目录说明计算机视觉计算机视觉DataScience数据科学作业所有的作业都提交在这个目录下,每个人创建属于自己的独立目录HR内推渠道Interview_Questions: 面试题集KnowledgeShare干货分享LearnFromZero从零单排NLP自然语言处理、自然语言处理OnePiece大航海PracticeProject实战项目PythonExercisePython练习、应用资源资源目录TechSalon技术沙龙WeeklyReport每周新鲜事、分享好项目、好资源使用说明命名规范文件夹命名规范必须为英文全部小写单词之间用下划线分割,例如nagios_check_tomcat第一个单词代表项目涉及应用,若有多个采用简写,最多2

    基于java的学生社团管理系统设计与实现.docx

    基于java的学生社团管理系统设计与实现.docx

    学习微服务框架SpringCloud的一些示例代码.zip

    学习微服务框架SpringCloud的一些示例代码

    基于java的数字家庭网站设计与实现.docx

    基于java的数字家庭网站设计与实现.docx

Global site tag (gtag.js) - Google Analytics