AJAX专题

在正文之前,我要哔叽几句,骂骂人:

现在不少框架说什么数据驱动,什么不操作DOM,这绝对的是不负责任,简直就是真正的行业败类,没有DOM,还写什么JS、还说什么绑定,不要因为封装了,蒙蔽那些初学者;皮之不存、毛将焉附,没有DOM的操作,还谈什么数据绑定。不要为了市场炒作而做出害人之举,又或自身对DOM的理解根本就是错误了的,还人云亦云,出来丢人现眼。

AJAX词条

简介

全称: `Asynchronous JavaScript and XML(异步JavaScript 和 XML);
AJAX并不是一种编程语言,而是一种数据发送与接收的技术解决方案;
AJAX涉及到的技术:HTML、CSS、JavaScript、XML(现在广义来说是定义一种标准化的数据结构)、HTTP协议、服务器端API(应用程序接口)、跨域、安全;
AJAX让Web开发能有更好的用户交互体验,在数据的发送与请求中做到更快更简洁;
使用AJAX可以实现文件上传及上传进度条的展示以增强用户的体验
慕课解释: ajax只是javascript(以下简称js)中众多功能中的一个功能,是获取数据的另外的一种途径,用以提高我们在使用软件时的用户体验以及减少在加载数据时的脏数据并同时提高数据的呈现,从而达到更好的系统架构。

伴随着H5的到来、移动端应用、混合式开发的普及,AJAX在我们的程序中大放异彩,作为我们开发者必备的技能之一:

现在的AJAX已不在是刚出来时存粹的方便数据的读取,现在更是涉及到系统架构、合理的数据格式定义、接口安全、数据安全;

数据加载得越少越好从而减少网络带宽、提高并发访问;

成为了行业数据通信格式的标准,多平台多系统支持;

接下来,让我们以实际的例子来学习与理解这个东西吧。

当然在jq已成为必备工具的今天,我们在这里也将会使用jq为我们带来的这方面的使用方法;

要完全掌握ajax的应用,我们必须要具javascript的基础知识,包括当不限于对象直接量/数组直接量/JSON(JavaScript Object Notation)、eval以及XMLHttpRequest这三个技能点:

当然还会有涉及到其他的知识面以及更多的应用场景,不过我们今天的主题是AJAX,那么就以我们在实际项目中常用的数据格式为主;

第一步:对象直接量/数组直接量

对象直接量格式:{"键名":"键值"} 数组直接量格式:[值1,值2]
我想这个格式很熟悉吧,这是定义一个对象/数组变量的语法格式,这种语法格式的叫做直接量;在我这里形如这种键名/键值表现格式的数据,统一都称之为键值对数据格式,还有我们已学习过的比如form表单的表单名及值,GET/POST传值中的名称与值(key1=value&key2=value2)
例:
对象:var news={"title":"文章标题","matter":"文章内容","id":1,"shijian":123456789};
数组:var week=["日","一",'二','三','四','五','六'];
var data=[{"title":"文章标题1","matter":"文章内容1","id":1,"shijian":123456789},{"title":"文章标题1","matter":"文章内容2","id":2,"shijian":123456789}]
注意:不建议大家现在使用let,在实际项目实践中,安卓5.0及以下的系统不支持ES6的语法,我们被这个坑可是坑苦了(虽然有转换工具,但是都是更多的人力成本、时间成本的付出),建议现在不要使用,在过个几年在用吧(2022年),做项目不是绣新技能。切记!!

第二步:JSON

格式1:'{"键名":"键值"}'
格式2:'[值1,值2]'
很奇怪吧,怎么看上去与第一步的直接量格式一样呢,但却不能认为是真正的JS中的对象与数组,实际上他们是以字符串形式表示的形如对象/数组直接量的字符数据。为了避免迷糊,直接点来说,就是一个字符串,不要有什么大惊小怪的。但是这种格式的字符串,我们给他取了个名字叫JavaScript Object Notation,简称JSON;
注意啦,这种由单/双引号引起来的数据是什么数据类型呢?是不是我们已掌握的字符串?当然是了,千万要注意,虽然里面形式对像,但在这里实实在在的是一个字符串;思考一下,我为什么使用的是单引号,如果用双引号,应该怎么写。 在这里我要强调3遍(重要): 这种类似对象的数据的字符中包含的对象的键名及字符串键值一定要用双引号你可能要问为什么,因为:多种开发语言在使用的时候只支持双引号,切记。
例子:
对象形式:var josn='{"title":"文章标题","matter":"文章内容","id":1,"shijian":123456789}';
数组形式:var data='[{"title":"文章标题1","matter":"文章内容1","id":1,"shijian":123456789},{"title":"文章标题1","matter":"文章内容2","id":2,"shijian":123456789}]'

第三步:JSON到对象/数组

根据上面的数据,我们也看到了,字段串形式的对象与数组就差那么一点点就与咱们JS中真正的对象与数组一样了,如果基础好的同学早就知晓可以使用JS提供的eval函数(方法)进行转换,当然,还有一种方法,大家可以自行查阅。
eval的用法很简单,以上面的例子为例,只需要如下:
var json=eval('({"title":"文章标题","matter":"文章内容","id":1,"shijian":123456789})');
必须要加括号,重要。至于为什么,大家可以自行查阅一下资料

第四步:数据绑定

有了以上的基础进阶,现在我们进入实际的应用阶段,我们通过上面的例子可以看到,我写的是数据是与文章有相关的,因为在我们实际的项目的,这个是必备,我个人认为这也是项目中最基础的一个功能模块了。我们每天上网,看新闻、写博客,看我写的这篇文章等等等级我们一个项目必备的。文章的:增、删、改、查,这几个操作终身都离不开。

今天我们先来说说数据绑定,通俗来说,就是把我们上面的数据,以某种更合理合适的方式呈在用户看到的UI(软件界面/网页),但然大家也知道啦,使用我们的武器(HTML/CSS)写的网页;我想大家在实际的学习或应用可已使用为innerHTML、document.write等方式向我们的HTML页面中增加过数据了,是的,我们用的就是innerHTML。那么我们下面将通过一个例子来进行学习同时在这个例子中我们还将涉及到单页面应用

首先我们来看一个与文章相关项目UI:
通过这个UI,我们看到了文章列表与文章详情页,那个我们现在就以这两个页面来进行实际的操作。

文章列表页:


文章详情页:

 

1、列表页面布局:
先看布局(以演示为主不以UI图片为准)


第一种(传统型):
<ul id="dataitem">
    <li><a href="view.html?dataid=1">文章标题</a></li>
    <li><a href="view.html?dataid=2">文章标题</a>题</li>
    <li><a href="view.html?dataid=3">文章标题</a></li>
</ul>

第二种(传统推荐型):
<div id="dataitem">
    <a href="view.html?dataid=1">文章标题</a>
    <a href="view.html?dataid=1">文章标题</a>
    <a href="view.html?dataid=1">文章标题</a>
</div>

第三种(列表型):
<ul id="dataitem">
    <li data-id="1">文章标题</li>
    <li data-id="2">文章标题</li>
    <li data-id="3">文章标题</li>
</ul>


第四种(列表精简型):
<div id="dataitem">
    <a did="1">文章标题</a>
    <a did="2">文章标题</a>
    <a did="3">文章标题</a>
</div>

以上4种布局是在我们的项目是经常用到的;

在这里重要强调:代码越精简越好,命名越语义化越好,标签的选择同样道理,我很悲哀的很多人或老师一味的强调用DIV,简直是大错特错,特别的一个例子:该用表格(table)的时候却一定要用其他的标签模拟,简直就是误人子弟,更是错误的认知HTML语言。

可以看一下我们对项目的开发规范说明:项目开发规范

第一二种:通过我们前期所掌握的网页制作知识,我们会认为这里需要用超链接并跳转一个文章的详情页面,也是我们熟知的并认为应该是这样子的。
第三四种:是我们今天的AJAX主角必须要掌握的,同时我们还会使用单页面的应用。
2、详情页面布局:
<h2 id="title">标题</h2>
<div id="matter">内容</div>

接下来,我们使用innerHTML进行数据呈现操作,把上面我们定义的数据呈现出来:

以第三种布局为例,直接上代码(基础知识):
<script type="text/javascript">
    (function(){
        //列表数据绑定
        var data=eval('([{"title":"文章标题1","matter":"文章内容1","id":1,"shijian":123456789},{"title":"文章标题1","matter":"文章内容2","id":2,"shijian":123456789}])');
        var item=document.getElementById("dataitem"),rows={},html="";
        for(var idx in data)
        {
            rows=data[idx];
            html+='<li data-id="'+rows["id"]+'">'+rows["title"]+'</li>'
        }
        item.innerHTML=html;
        
        //详情数据绑定
        var json=eval('({"title":"文章标题","matter":"文章内容","id":1,"shijian":123456789})');
        document.getElementById("title").innerHTML=json["title"];
        document.getElementById("matter").innerHTML=json["matter"];
    })();
</script>
在以上代码中,我们还只是应用了已学习基础知识,大家会问“老师,说了这么多,怎么都是我们以前学的东西啊”,这不就还是以前这些吗?与AJAX有什么关系呢,那AJAX究竟是啥东西啊。
是啊,AJAX就是包含这些东西,他不是一个什么技术,而是一系列知识点集合应用的统称,当然在这里我们必不可少的还有XMLHttpRequest对象,在是我们AJAX技术真正的核心点,放在下面来说。
通过以上的例子,大家知道了json数据,也知道了数据的绑定,我们也直观的看到了这些数据,可是我们也知道,在我们平常实际的上网体验中,我们看到的数据是变化的,我们可以选择不同的文章,查看对应的文章内容;
我们可以增加、修改、删除、评论、打分、购买、支付等一系列的操作使用;
那这些操作,这些数据是从那里来、到那里去的呢;这里就涉及到后端开发以及服务器等项目相关的成员了,不过今天我们只关注一点:API(应用程序接口/数据接口)

第五步:API数据接口

请点击打开这个API接口演示的地址: http://www.rsseasy.com/api/local/list/article
看一看,有什么规律,数据格式即是我们上面所定义的JSON格式;
到我这里,我想大家已明白了,我们需要把这里所见到的数据呈现到我们的UI,那这个数据怎么得到呢,怎么如以上数据绑定的方式呈现到用户的眼前呢?
所以需要XMLHttpRequest登上舞台了,咱们就需要用它来实现这个功能。
以实例说话(上代码):
<script type="text/javascript">
    (function(){
        var xhr=new XMLHttpRequest();  //实例化
        xhr.onreadystatechange=function(){  //监听状态改变事件
            if(this.readyState==4&&this.status==200)   //检测请求状态值与http状态码
            {
                //this.responseText通过这个属性获取api接口返回的数据(返回的任何数据者是字符串格式的)
                var data=eval('('+this.responseText+')');
                var item=document.getElementById("dataitem"),rows={},html="";
                for(var idx in data)
                {
                    rows=data[idx];
                    html+=''+rows["title"]+'
'
                }
                item.innerHTML=html;
            }
        }
        xhr.open('get','http://www.rsseasy.com/api/local/list/article',true);  //指定请求的方式,同学们,想一想以前学习html候form表单提交数据的现从种方式get/post,这里其实是一样,不要被应用场景的外表给蒙蔽了,这一切都是HTTP协议制定的规矩,大家(浏览器、后台开发语言、服务器、一切与web开发相关的)都得准守;
        xhr.send(null);  //发送请求,去open中指定的api地址去读取数据;
    })();
</script>

最后一步:全面了解XMLHttpRequest

XMLHttpRequest对象提供的js操作Http请求的可能,即通过此对象可以向url发送或获取数据,进行数据的增、删、改、查操作;形如html中form表单提交数据一样,不过form表单提交时页面会进行重新加载(提交到当前页面会刷新、提交到非当前页面会打开另一个页面);而其中最重要的特性是提供异步(后台)请求http的能力,让用户在操作数据时感觉不到如form表单提交数据时产生的重载或打开页面,以此达到更好的用户体验以及更轻量级的数据交换;

XMLHttpRequest的存在核心就是为了减轻加快数据交换而存在,所以在进行系统设计的,必须去掉不必要的数据、去掉脏数据用以提高http请求达到加快获取数据是核心;

XMLHttpRequest这种特性在其他任何语言中也是存在的,只有名字不一定相同,是以线程的方式去实现的,其实的核心思想是请求指定的url以获取当地址的数据;
属性
<table style="width:100%">
    <thead>
        <tr>
            <th style="width:150px">名称
            </th>
            <th>
            描述
            </th>
            <th>
            备注
            </th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>readyState</td>
            <td>获取XMLHttpRequest状态;</td>
            <td>0、XMLHttpRequest对象已创建或已被 abort() 方法重置;<br />
            1、open() 方法已调用, send() 方法未调用;<br />
            2、Send() 方法已调用;<br />
            3、http头部信息数据全部返回,开始接受数据;<br />
            4、数据已加载完毕。
            </td>
        </tr>
        <tr>
            <td>status</td>
            <td>获取请求返回的HTTP状态码。</td>
            <td>1、当readyState为3与4时可用,或则出错;<br />2、在实际中项目中都与readyState为4时配合使用;<br />3、HTTP常见状态吗(200:服务器返回正确、400:请求的地址不存在、500:服务器端程序出错,其他状态码请查阅HTTP协议)</td>
        </tr>
        <tr>
            <td>statusText</td>
            <td>获取请求返回的HTTP状态码对应的文本信息。</td>
            <td>1、200:OK、400:Not Found;<br />2、其它请查阅HTTP协议</td>
        </tr>
        <tr>
            <td>responseType</td>
            <td>获取或设置数据的类型,也决定了response属性中数据的的数据类型</td>
            <td>1、空字符串<br />2、arraybuffer,二进制数据;<br />3、blob,二进制数据blob;<br />4、document 返回xml,responseXML有用;<br />5、json<br />6、text,与空字符串相同,默认。<br />7、请注意在使用这些值时的兼容性。</td>
        </tr>
        <tr>
            <td>response</td>
            <td>其类型取决于responseType的值</td>
            <td>与responseType配合使用</td>
        </tr>
        <tr>
            <td>responseText</td>
            <td>以字符串的形式获取接收到的数据</td>
            <td>当readyState为3时,部分数据;<br />为4时完整的数据;<br />所以我们需要在readyState为4时在进行数据的编程处理</td>
        </tr>
        <tr>
            <td>responseXML</td>
            <td>以xml的格式获取数据。</td>
            <td>1、xml(可扩张标记语言)以前制定数据传输交换标准;<br />2、返回的xml数据以Document对象存储。<br />3、使用此方法必须要求返回的数据是xml标准格式的数据<br />4、xml为已不推荐使用</td>
        </tr>
        <tr>
            <td>timeout</td>
            <td>设置请求的超时时间</td>
            <td>当超出该时间时,请求自动结束</td>
        </tr>
        <tr>
            <td>FormData</td>
            <td>表单数据</td>
            <td>模拟html表单进行数据提交</td>
        </tr>
        <tr>
            <td>upload</td>
            <td>数据上传过程</td>
            <td></td>
        </tr>
    </tbody>
</table>
方法
<table style="width:100%">
    <thead>
        <tr>
            <td>名称</td>
            <td>说明</td>
            <td>备注</td>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>abort()</td>
            <td>终止已发送的请求</td>
            <td>当调用send后使用</td>
        </tr>
        <tr>
            <td>getAllResponseHeaders()</td>
            <td>获取所有的响应头</td>
            <td>当readyState值为3或4时可用;响应头相关的规范见http协议</td>
        </tr>
        <tr>
            <td>getResponseHeader(name)</td>
            <td>获取指定name的响应头值</td>
            <td>当readyState值为3或4时可用,不存在则返回null</td>
        </tr>
        <tr>
            <td>open(method,url,asyn)</td>
            <td>初始化一个请求</td>
            <td>设置请求的相关参数;<br />method:请求的方式,常用get或post<br />url:请求的地址;<br />asyn:是否异步true或false,默认异步,用onreadystatechange事件配合使用;</td>
        </tr>
        <tr>
            <td>send(params)</td>
            <td>发送请求</td>
            <td>params:当post方式提交数据的参数,可为null</td>
        </tr>
        <tr>
            <td>setRequestHeader()</td>
            <td>设置HTTP请求头的值</td>
            <td>在open()之后、send()之前调用;<br />与后台配合使用</td>
        </tr>
    </tbody>
</table>
事件:
名称说明onabort当调用abort()时触发onerror当请求出现错误时ontimeout当超时时触发onload当请求成功时出发onloadend当请求结束时触发upload.progress当上传进度发生变化时出发。
在upload属性中使用
FormData方法,以下方法并非所有浏览器支持
<table style="width:100%">
    <thead>
        <tr>
            <td style="width:150px">名称</td>
            <td>说明</td>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>onabort</td>
            <td>当调用abort()时触发</td>
        </tr>
        <tr>
            <td>onerror</td>
            <td>当请求出现错误时</td>
        </tr>
        <tr>
            <td>ontimeout</td>
            <td>当超时时触发</td>
        </tr>
        <tr>
            <td>onload</td>
            <td>当请求成功时出发</td>
        </tr>
        <tr>
            <td>onloadend</td>
            <td>当请求结束时触发</td>
        </tr>
        <tr>
            <td>upload.progress</td>
            <td>当上传进度发生变化时出发。<br />在upload属性中使用</td>
        </tr>
    </tbody>
</table>
upload数据上传属性事件
<table style="width:100%">
    <thead>
        <tr>
            <th style="width:150px">名称
            </th>
            <th>
            描述
            </th>
            <th>
            备注
            </th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>readyState</td>
            <td>获取XMLHttpRequest状态;</td>
            <td>0、XMLHttpRequest对象已创建或已被 abort() 方法重置;<br />
            1、open() 方法已调用, send() 方法未调用;<br />
            2、Send() 方法已调用;<br />
            3、http头部信息数据全部返回,开始接受数据;<br />
            4、数据已加载完毕。
            </td>
        </tr>
        <tr>
            <td>status</td>
            <td>获取请求返回的HTTP状态码。</td>
            <td>1、当readyState为3与4时可用,或则出错;<br />2、在实际中项目中都与readyState为4时配合使用;<br />3、HTTP常见状态吗(200:服务器返回正确、400:请求的地址不存在、500:服务器端程序出错,其他状态码请查阅HTTP协议)</td>
        </tr>
        <tr>
            <td>statusText</td>
            <td>获取请求返回的HTTP状态码对应的文本信息。</td>
            <td>1、200:OK、400:Not Found;<br />2、其它请查阅HTTP协议</td>
        </tr>
        <tr>
            <td>responseType</td>
            <td>获取或设置数据的类型,也决定了response属性中数据的的数据类型</td>
            <td>1、空字符串<br />2、arraybuffer,二进制数据;<br />3、blob,二进制数据blob;<br />4、document 返回xml,responseXML有用;<br />5、json<br />6、text,与空字符串相同,默认。<br />7、请注意在使用这些值时的兼容性。</td>
        </tr>
        <tr>
            <td>response</td>
            <td>其类型取决于responseType的值</td>
            <td>与responseType配合使用</td>
        </tr>
        <tr>
            <td>responseText</td>
            <td>以字符串的形式获取接收到的数据</td>
            <td>当readyState为3时,部分数据;<br />为4时完整的数据;<br />所以我们需要在readyState为4时在进行数据的编程处理</td>
        </tr>
        <tr>
            <td>responseXML</td>
            <td>以xml的格式获取数据。</td>
            <td>1、xml(可扩张标记语言)以前制定数据传输交换标准;<br />2、返回的xml数据以Document对象存储。<br />3、使用此方法必须要求返回的数据是xml标准格式的数据<br />4、xml为已不推荐使用</td>
        </tr>
        <tr>
            <td>timeout</td>
            <td>设置请求的超时时间</td>
            <td>当超出该时间时,请求自动结束</td>
        </tr>
        <tr>
            <td>FormData</td>
            <td>表单数据</td>
            <td>模拟html表单进行数据提交</td>
        </tr>
        <tr>
            <td>upload</td>
            <td>数据上传过程</td>
            <td></td>
        </tr>
    </tbody>
</table>
2、在以上例子中我们使用的是get方式,在这里我们需要回顾一下get与post的请求的知识;
    get方式:http://www.rsseasy.com/api/local/list/article?key1=value1&key2=value2&key3=value3
    传递的参数及值是直接在整个url地址中;
    
    post方式:传递的方式可以通过body方式进行传递,这个body方式,我们就认为参数与值是以隐藏的方式传递,要理解这种方式以我的经历来看,需要多实际写项目才能理解;
    
    当然在使用post的时候,同样是可以在url地址后面增加参数与值的,这种方式我们先理解为综合的方式,亦即get与post共同使用,这是允许的,很多人在开始学习的时候这点是没有掌握。
3、怎么通过XMLHttpRequest进行Post方式进行数据请求呢?看代码
    xhr.open('post','http://www.rsseasy.com/api/local/list/article',true); 
    xhr.send(key1=value1&key2=value2&key3=value3); 
4、xhr.open方法中的true表示异步请求,这个功能才是ajax真正大放异彩的点睛之笔,没有他就没啥ajax这个东西了。
那什么是异步呢,看代码:
<script type="text/javascript">
    
    (function(){
        //我们的代码结构:顺序、循环、条件;
        //正常来说,我们的代码是从上向下执行的(当然事件除外),比如:
        alert(1);
        alert(2);
        alert(3);
        
        //以上代码我们知道,提示框按1、2、3顺序显示
        //当然我们也可以用console.log(text),不过都一样,不过作为前端开发者也必须要会用开发者工具,差不多各个浏览器都提供,F12就出来了;
        //那如果我们把代码与ajax代码混合起来以实际的结果来理解异步(这是一个术语,不要让自己烧脑,我学习的时候被乱七八糟的术语搞得以为多高大上的东西,其实不要去理会,主要是看具体是什么样的一种现象与结果)
        
        alert(1);
        var xhr=new XMLHttpRequest();
        xhr.onreadystatechange=function(){
            alert(2);
            if(this.readyState==4&&this.status==200)
            {
                alert(this.responseText);
                var data=eval('('+this.responseText+')');
                var item=document.getElementById("dataitem"),rows={},html="";
                for(var idx in data)
                {
                    rows=data[idx];
                    html+=''+rows["title"]+'
'
                }
                item.innerHTML=html;
            }
        }
        xhr.open('get','http://www.rsseasy.com/api/local/list/article',true); 
        xhr.send(null); 
        alert(3);
        
        //在来看以上代码执行的结果,我们可以看到提示框顺序是:1、3、2,那这就是所谓异步的执行规则
        //如果大家对事件很熟悉的话,其实更好理解,我们知道如点击事情,是在当我们点击发生的时候才会去执行代码;
        //那么在我们这里,我们看到了有onreadystatechange这么一事事件,这个事件的意思是当我们请求的状态发生变化时执行我们定义的代码;
        //在以例子中,我们可以看到:readyState与status这两个对像属性名称,他们分别是:
        //readyState:表示在向指定的url地址请求数据时的几个状态(1、2、3、4)、我们只关注值为4就行了,其他咱们不需多费口舌;4表示请求返回了数据,也就是多服务器上把数据都拿到了,就相当于我们平时下载文件,不管用什么工具,最后文件都下载完毕。这个4就表示下载完毕了,在上面的例子,也就是我们得到了我们看到的接口数据;
        //status:是HTTP的状态码,这里需要大家自行去阅读一下http协议相关的内容;不过我这里只介绍我们常见的,也许有些同学已见过了,如:400,404,502,以上这几个都是错误码;那我们只关心200,这个表示服务返回数据是成功的,无任何其他的错误。
        //用alert弹出来看下数据,与我们直接打开API地址是一样的,通过上面代码我们也应该知道了responseText就是得到我们从API中获取到的数据,用以进行下一步的开;
        //好了,言归正传,如果把这个true改成false呢,那在来看看顺序,但是我们真的不需要,只是作为一个了解吧;
        //至此,我们已对ajax的基于项目上要用的知识面说到这里了;
        //在任何一个其它语言中,其实也有这类似的功能,还有多线程呢的,如果你学习过java\c#等这些开发语言就明白了;
    })();
    
</script>

综合实例:

完成以上学习中所使用的文章例子,以单页面的形式完成绑定文章列表并点击文章列表中的文章查看文章详情,我们来进行一个更全面的使用,以及封装一个通用的ajax类,因为在我们的项目,这个是必须的,封装是一个检查开发人员编码能力的主要指标之一,如果这都不懂,你根本不要说自己是搞开发的,还是好好的回炉吧。
何为单页面,也不要被这个术语吓住了,其实就是在一个html文件中写下项目所有页面,比如咱们这个只有两个页面放在一个body里,如果有多少,就一样放在里面;
//HTML内容
<html>
    <head>
        <style type="text/css">
            section{display:none}
            #listpage{display:block}
            a{display:block}
        </style>
    </head>
    
    <body>
        //文章列表页面
        <section id="listpage">
            <div id="dataitem">
                <a data-id="1">文章标题</a>
                <a data-id="2">文章标题</a>
                <a data-id="3">文章标题</a>
            </ul>
        </section>
        
        //文章详情页面
        <section id="detailpage">
            <a href="#listpage">返回</a>
            <div id="dataitem">
                <h2 id="title">文章标题</h2>
                <div id="matter">文章内容</div>
            </div>
        </section>
    
        //样式大伙就自己好好的按效果图完成吧
    </body>
</html>
//JS代码
<script type="text/javascript">

//以对象的方式直接封装,还可以以类的思想进行封装;虽然js到了es6,引入了不少语法结构的东西,不过我不认为这是什么好的东西,看上去是繁花似锦,不过只是绣花枕套虚有其表而以,js的规范应该是多增加点与项目相关的实际功能才是正确的方向以及优化性能安全为主
var ajax=
    {
        "host":"http://www.rsseasy.com/api/local/",
        "get":"json",
        "parse":function(parmas){
            if(parmas&&parmas.constructor==Object)
            {
                var arr=[];
                for(var key in parmas)
                {
                    arr=key+'='+encodeURIComponent(params[key]).replace(/!/g, "%21").replace(/~/g, "%7E").replace(/'/g, "%27").replace(/\(/g, "%28").replace(/\)/g, "%29").toLowerCase();  //进行url utf-8编码数据,解决JS中编码与服务器编码不一致的问题
                }
                return arr.join('&');
            }
            return ""
        },
        "get":function(api,parmas,onsuccee,onerror){
            parmas=this.parse(parmas);
            if(parmas&&api.indexOf(".")>-1)
            {
                api=api.replace("?",parmas+"&");  //
            }
            this.request("get",this.host + api,null,onsuccee,onerror);
        },
        "post":function(api,parmas,onsuccee,onerror){
            this.request("post",this.host + api,this.parse(parmas),onsuccee,onerror);
        },
        "request":function(method,url,parmas,onsuccee,onerror){
            var xhr=new XMLHttpRequest();
            xhr.onreadystatechange=function(){
                try
                {
                    if(this.readyState==4&&this.status==200&&onsuccee&&onsuccee.constructor==Function)
                    {
                        onsuccee(eval('('+this.responseText+')'),xhr);
                        return;
                    }
                }catch(ex){}
                
                if(onerror&&onerror.constructor==Function)
                {
                    onerror(this.responseText,xhr)
                }
            }
            xhr.open(method,url,true); 
            xhr.send(parmas); 
        },
    }
    //参数说明:
    //parmas:url参数,可以是大家熟悉的>key1=value1&key2=value2&key3=value3
    //onsuccee:在获取数据成功时回掉函数,并且把数据传递给调用处
    //onerror:在获取数据错误时回掉函数
    
    //单页面应用的核心,页面之间的切换
    window.onhashchange = function () {
        var pages = document.getElementsByTagName('section');
        for (var i = 0; i < pages.length;i++)
        {
            pages[i].style.display = "none";
        }
        document.querySelector(location.hash).style.display = "block";
    }
    
    //获取文章列表数据
    ajax.get("list/article",null,function(data){
        var item=document.getElementById("dataitem"),rows={},html="";
        for(var idx in data)
        {
            rows=data[idx];
            html+='<a data-id="'+rows["id"]+'">'+rows["title"]+''
        }
        item.innerHTML=html;
        
        var links=item.getElementsByTagName("a");  //查找文章列表的文章
        for(var idx in links)
        {
            //增加点击事件,当点击的时候获取当前点击文章的详细信息
            links[idx].onclick=function(){
                location.hash="#detailpage";
                //通过url传递参数与值到后台写的接口,在这个接口中要求的参数名称为id
                ajax.get("details/article?id="+this.dataset.id,null,function(data){  
                    document.getElementById("title").innerHTML = data["title"];
                    document.getElementById("matter").innerHTML = data["matter"];
                });
            }
        }
    });
</script>

拓展:Jquery中使用AJAX

jq是我们已很熟悉的一个JS功能,我比较喜欢是的他封装的选择器,并且我们自己更是jq的基础上增加了更多的扩展功能,其实在我眼中,真正用好jq的没有几个人,被今天出一个框架明天出一个框架,这个好那个好的给带到的一个只会用工具的的工人,而不是真正的编程者。
<script type="text/javascript">
//在以上的例子的,我们自己封装了ajax的get与post方法
//使用jq之前需要引入jq的js文件
//jq ajax实现,用get方式获取数据,代码:
$.get(ajax.host+"list/article",function(data){
    data = eval('('+data+')');
    var rows={},html="";
    $.each(data,function(idx,rows){
        html+=''+rows["title"]+''
    });
    //写入HTML,查找所有的li子元素并增加点击事件
    $("#dataitem").html(html).find(">a").click(function(){
        location.hash="#detailpage";
        var t=$(this),id=t.data("id");
        
        $.get("details/article?id="+id,function(data){
            data = eval('('+data+')');
            $("#title").html(data["title"]);
            $("matter").html(data["matter"]);
        });
    });
});
</script>
好了,以上是我们本次讲解的ajax,在这个文章中我们中用到ajax的获取数据并呈现的功能,当然还有如我们提到的项目必须使用的增、删、改这几种操作,在我们下一次的《AJAX实战》课程中,将全面通过一个项目进行实际操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值