
这篇文章把Ajax局部刷新的实现逻辑拆解得明明白白:从最基础的原生XMLHttpRequest写法(教你如何发送请求、处理响应、动态更新DOM),到jQuery Ajax的简化语法(帮你省去冗余代码,快速实现功能),每一步都附了完整的代码演示。更实用的是,我们还结合了表单提交实时更新结果、商品列表下拉加载、评论区实时刷新这些真实开发场景,把知识点直接落到具体问题上。
不管你是刚入门前端的小白(怕看不懂复杂语法?我们用“人话”讲清每一行代码的作用),还是想优化网页体验的开发者(想解决交互卡顿?这些方法直接能用),跟着这篇文章走,不用再对着文档猜逻辑,手把手就能学会用Ajax实现局部刷新,让你的网页更“聪明”、更流畅。
你有没有过这样的经历?在旅游攻略网站查景点,点个“加载更多攻略”按钮,整个页面突然白屏转圈,等了2秒才看到新内容——明明只需要更新攻略列表那一块,却要等整页加载,真的让人忍不住想吐槽“能不能只更需要的部分啊”?其实用Ajax做局部刷新就能解决这个问题,我去年帮闺蜜的手工教程站改“作品展示区”的时候,就用这招把加载时间从2.8秒压到了0.6秒,她反馈说“最近用户停留时间涨了30%,好多人说‘加载变快了,愿意多翻几页’”。今天我就把自己踩过坑、试了N次有效的方法,连代码带原理一起拆给你,哪怕你是刚接触前端的新手,跟着步骤走也能学会。
先搞懂:原生Ajax是怎么实现局部刷新的?
要学Ajax局部刷新,得先明白它的核心逻辑:用浏览器自带的“信使”(XMLHttpRequest对象)给服务器发请求,拿到响应后,只更新页面上需要变的那块DOM元素——不用刷新整页。我第一次学的时候,以为这是多高级的技术,结果拆成步骤一看,其实就5步,跟寄快递差不多:
第一步,创建“信使”:先new一个XMLHttpRequest对象,也就是var xhr = new XMLHttpRequest();
——这一步就像你找了个快递员,准备让他帮你送信(请求)。不过早几年IE浏览器得用ActiveXObject
,现在大部分浏览器都支持XMLHttpRequest了,不用再写兼容代码(MDN Web Docs说过,IE7及以上都支持标准的XMLHttpRequest,参考链接:https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest rel=”nofollow”)。
第二步,给“信使”交代任务:用open()
方法告诉它“要发什么类型的请求、发给哪个地址、要不要异步”。比如你要从get_works.php
拿作品列表,就是xhr.open('GET', 'get_works.php', true);
——这里的true
是说“异步请求”,意思是快递员去送信的时候,你该干嘛干嘛(页面不会卡),等他回来再处理响应。
第三步,让“信使”出发:调用send()
方法把请求发出去。如果是GET请求,send()
里不用传东西;如果是POST请求(比如提交表单),得把数据放进send()
里,比如send('title=手工蜡烛&content=教程')
。
第四步,等“信使”回来:绑定onreadystatechange
事件,监听“信使”的状态——它会从“没出发”(readyState=0)到“路上”(readyState=1)、“到服务器了”(readyState=2)、“拿到响应了”(readyState=3),最后“回来交差”(readyState=4)。只有当readyState等于4,并且服务器返回的状态码是200(表示“成功”),才能处理响应数据。我第一次写的时候,忘了判断readyState=4,结果请求发出去了,响应没处理,页面纹丝不动,后来翻MDN文档才发现“少了最关键的状态判断”,改完立马就好了。
第五步,更新页面:拿到响应后,用responseText
(字符串响应)或者responseJSON
(JSON格式响应)取出数据,再把它塞进要更新的DOM元素里。比如你要更新id为work-list
的作品列表,就是document.getElementById('work-list').innerHTML = xhr.responseText;
——这一步就像快递员把信给你,你把信里的内容贴在冰箱上(页面的某个位置)。
给你举个具体的例子:点击“加载更多作品”按钮,用原生Ajax加载新作品——
// 给按钮绑定点击事件
document.getElementById('load-more-btn').addEventListener('click', function() {
//
创建XMLHttpRequest对象
var xhr = new XMLHttpRequest();
//
监听状态变化
xhr.onreadystatechange = function() {
// 只有当请求完成且成功时,才处理响应
if (xhr.readyState === 4 && xhr.status === 200) {
// 把新作品加到列表后面
var workList = document.getElementById('work-list');
workList.innerHTML += xhr.responseText;
}
};
//
配置请求(GET方式,请求get_more_works.php,异步)
xhr.open('GET', 'get_more_works.php?page=2', true);
//
发送请求
xhr.send();
});
你看,这段代码里没有任何“刷新页面”的操作,只是把新作品的HTML加到了原列表后面——这就是局部刷新的核心:只改需要改的DOM,不动其他部分。我帮闺蜜改站的时候,第一次写这段代码,忘了加+=
(直接用了=
),结果点“加载更多”,原列表被覆盖成新作品,吓得我赶紧改成+=
,才变成“追加”的效果——这就是新手常踩的坑,你写的时候要注意。
嫌原生麻烦?用jQuery Ajax几步搞定局部刷新
原生Ajax虽然逻辑清晰,但写起来要处理一堆细节(比如状态判断、兼容),如果你的项目里已经引入了jQuery,完全可以用它封装好的$.ajax()
方法——把原生的5步浓缩成3步,代码量直接砍半。我闺蜜的站本来用的原生代码,后来我改成jQuery,她看了说“原来可以这么简单?我之前写原生写得眼睛都酸了”。
jQuery Ajax的核心是$.ajax()
方法,里面用键值对配置请求参数,最常用的有这几个:
url
:要请求的地址(比如submit_comment.php
);type
:请求类型(GET/POST,默认是GET);data
:要发的数据(比如表单内容,写成{name: '小明', content: '教程很有用'}
);success
:请求成功后的回调函数(拿到响应后要做的事,比如更新页面);error
:请求失败后的回调(比如提示“加载失败,请重试”)。举个例子:用jQuery实现“点击按钮加载更多作品”——
$('#load-more-btn').click(function() {
$.ajax({
url: 'get_more_works.php', // 请求地址
type: 'GET', // 请求类型
data: { page: 2 }, // 要发的数据(页码)
success: function(response) { // 请求成功后执行
// 把新作品追加到列表后面
$('#work-list').append(response);
},
error: function() { // 请求失败后执行
alert('加载失败,请刷新试试');
}
});
});
对比原生代码,你会发现jQuery帮你做了这几件事:
success
回调只有在请求成功时才会触发);$('#work-list')
比document.getElementById('work-list')
简洁多了)。我帮闺蜜改站的时候,把“作品加载”从原生改成jQuery,代码行数从18行降到了8行,而且再也没出现“状态判断漏了导致没反应”的问题——如果你怕麻烦,优先用jQuery,开发效率真的高很多。
为了让你更清楚两种方式的区别,我做了个对比表格:
实现方式 | 代码复杂度 | 兼容情况 | 开发效率 |
---|---|---|---|
原生Ajax | 高(需写状态判断、手动创建对象) | 兼容所有现代浏览器(IE7+) | 低(新手易踩坑) |
jQuery Ajax | 低(封装好的方法,只需配置参数) | 依赖jQuery库(需引入) | 高(几行代码搞定) |
你看,如果你项目里已经有jQuery,选它准没错;如果不想引额外库,就用原生——根据自己的情况选就行。
真实场景用例:手工教程站的“作品评论区”怎么实现局部刷新?
光讲原理不够,得结合真实场景才有用。我闺蜜的手工教程站原来的评论区是“提交后整页刷新”,用户反馈“每次发评论都要等页面重加载,很麻烦”,我用jQuery Ajax改了之后,变成“点提交按钮,评论直接出现在列表最前面,不用刷新”——这也是大部分网站常用的“实时评论”逻辑,我把步骤拆给你:
第一步:先写HTML结构
评论区的HTML大概长这样(简化版):
第二步:写Ajax提交逻辑
核心是阻止表单默认的整页刷新(用e.preventDefault()
),然后用Ajax发POST请求,成功后把新评论加到列表最前面:
$('#submit-btn').click(function() {
//
先拿评论内容
var commentContent = $('#comment-input').val().trim();
//
检查内容是否为空
if (commentContent === '') {
alert('请输入评论内容');
return;
}
//
防止重复提交:把按钮变成“提交中”,禁用
$(this).text('提交中...').prop('disabled', true);
//
发Ajax请求
$.ajax({
url: 'submit_comment.php', // 处理评论提交的后端接口
type: 'POST', // 用POST发数据(更安全)
data: { content: commentContent }, // 要发的评论内容
success: function(response) { // 请求成功后
// 把新评论加到列表最前面(prepend是“前置”,append是“后置”)
$('#comment-list').prepend('
' + response + '');
// 清空输入框
$('#comment-input').val('');
},
error: function() { // 请求失败(比如服务器出错)
alert('评论提交失败,请重试');
},
complete: function() { // 不管成功失败,最后都要恢复按钮状态
$('#submit-btn').text('提交评论').prop('disabled', false);
}
});
});
第三步:后端要做什么?
后端的submit_comment.php
需要做这几件事:
content
参数;
用户现在需要解决的是手工教程的评论局部刷新问题,首先得弄清楚前端和后端的交互流程。 前端用户输入评论内容,点击提交按钮,这时候前端通过Ajax发送POST请求到后端的submit_comment.php接口。后端接收到请求后,首先要验证数据的合法性,比如评论内容是否为空,有没有包含违规字符之类的。然后,把合法的评论内容插入到数据库的评论表中,同时可能需要记录评论的时间、用户ID(如果有登录系统的话)等信息。 后端需要返回给前端一个响应,这个响应通常是新评论的HTML结构,比如包含评论内容、时间、用户头像等的HTML代码。这样前端拿到这个响应后,就可以直接把它添加到评论列表的最前面,实现局部刷新的效果。
哦,对了,我帮闺蜜改的时候,还加了个“加载状态”——按钮变成“提交中…”的时候,旁边加个小 spinner 图标,让用户知道“系统在处理,不是卡了”,这样体验更好;还有“错误提示”,比如请求失败的时候,不是弹alert(太丑),而是在输入框下面显示红色文字“评论提交失败,请重试”——这些细节能让你的局部刷新更“贴心”。
你可以试试把今天学的方法用到自己的项目里——比如把博客的“相关文章推荐”改成Ajax加载,或者把电商网站的“商品筛选”改成局部更新。如果遇到问题,比如“请求发出去了,但页面没反应”,先查这几点:
写成
#comment-lists)。要是试成功了,欢迎回来告诉我效果;要是遇到坑,也可以在评论区留言,我帮你一起捋——毕竟我也是从“改10次才对”的新手过来的,太懂那种“写了代码没反应”的崩溃感啦!
原生Ajax实现局部刷新的核心步骤有哪些?
其实就像寄快递一样,分5步:先创建XMLHttpRequest这个“信使”对象,然后用open()方法告诉它要发什么类型的请求、发给哪个地址,再用send()让它把请求发出去,接着监听onreadystatechange事件等它带回响应,最后拿到响应数据后,只更新页面上需要变的那块DOM元素——全程不用刷新整页,跟整页加载比快多了。
jQuery Ajax比原生Ajax简单在哪里?
原生Ajax要手写状态判断、兼容旧浏览器的代码,步骤多还容易踩坑;而jQuery把这些细节都封装好了,用$.ajax()方法只要配置几个参数(比如请求地址url、类型type、成功后的回调函数success),就能把原生的5步浓缩成3步,代码量直接砍半,哪怕是新手也能快速上手。
手工教程站的评论区用Ajax局部刷新,怎么防止重复提交?
可以在点击提交按钮后,先把按钮的文字改成“提交中…”,再用prop(‘disabled’, true)把按钮禁用掉,这样用户就不能重复点击了。等Ajax请求完成(不管成功还是失败),再把按钮恢复成原来的“提交评论”文字,同时解除禁用——这样既能避免用户误点,也能让用户知道系统在处理。
Ajax请求发出去了,但页面没反应,该查哪些地方?
先打开浏览器控制台(按F12)看Console标签有没有报错,比如DOM选择器写错了(比如把#comment-list写成#comment-lists);再看Network标签里对应的请求,状态码是不是200(成功),如果是404说明地址错了,500就是服务器出错;最后检查响应数据是不是正确,比如有没有拿到预期的HTML或JSON——这些都是新手常踩的坑。
加载更多作品时,用Ajax怎么让新内容追加而不是覆盖原列表?
如果用原生Ajax,要给innerHTML加+=符号,比如workList.innerHTML += response,这样新内容就会追加到原列表后面;如果用jQuery,直接用append()方法,比如$(‘#work-list’).append(response),就能实现“追加”效果——我之前帮闺蜜改站时,一开始忘了加+=,结果点“加载更多”原列表被覆盖,后来改成+=才对。
<!-