前端开发(HTML,CSS,VUE,JS)从入门到精通!第四天(DOM编程和AJAX异步交互)

八、DOM 编程

1.DOM(Document Object Model),文档对象模型:

将 HTM L文档进行模型化处理,形成一颗结构化的文档树,从而提供访问,修改文档的统一编程接口(API),一旦掌握 DOM 编程,就可以使用 JavaScript 操作整个 HTM L文档。(将 HTML 元素(HTML标签)抽象成一个一个的 DOM 对象,然后通过 JavaScript 来访问)

2.HTML 文档可以抽象成一颗 DOM 树,如下图:

HTML 文档通过浏览器解释执行之后形成了一颗 DOM 树,树上的每一个元素都是 DOM 对象,称为一个节点,然后节点又分为普通元素节点,属性节点,文本节点等等。

3.补充知识:BOM 对象(Browser Object Model),浏览器对象模型

(1)window 对象:

代表整个浏览器对象,是一个全局的对象,我们在 JavaScript 中声明的全局变量和全局函数默认情况下都归属于window 对象,window 对象是全局唯一的,在访问其属性和方法的时候,可以省略掉 "window." 前缀

(2)window 对象常用的属性:

document:文档对象,比如 document.write(内容) 等效于 window.document.write(内容)。

location:代表浏览器地址栏中的 url 地址

history:浏览器的历史记录

示例:

(3)window 对象的常用方法

alert():弹出提示框

prompt(提示信息):弹出输入框

var res = setInterval(函数, 定时时间):定时器,周期性的执行函数的代码,定时时间为毫秒记

clearInterval(res):关闭定时器

var res = setTimeout(函数,到期时间):设置一个到期时间之后执行一次函数就退出

clearTimeout(res):关闭Timeout

示例:轮播图

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>demo33</title>

<style>

*{

margin: 0;

padding: 0;

}

div.box{

width: 600px;

height: 450px;

margin: 40px auto;

border: 2px solid #ccc;

}

div.box > img{

width: 600px;

height: 450px;

}

</style>

</head>

<body>

<div class="box">

<img src="images/1.jpg" alt="" id="img">

</div>

<script>

var i = 0;//全局变量

//获取 img 这个 dom 对象

var img = document.getElementById("img");

//定时器:第一个参数为周期执行的函数,第二个参数为定时时间,毫秒记

setInterval(function () {

//重新给 img 这个 dom 对象的 src 属性赋值,切换图片

img.src = "images/" + ++i + ".jpg";

if(i >= 4){ //总共4副图片

i = 0;

}

}, 1000);

</script>

</body>

</html>

4.访问 HTML 元素(DOM对象)

(1)访问 HTML 元素有两种方式

① 使用 document 对象提供的方法来获取对应的 DOM 对象

② 利用 DOM 树的节点关系来访问

(2)使用 document 对象的方法来访问,window 对象的 document 对象提供了如下的方法来找到 HTML 元素(DOM对象)

① document.getElementById(idVal):根据HTML元素的id值来找到该DOM对象。

② document.getElementsByName(name):根据HTML元素的name属性来找到该DOM对象的集合。

③ document.getElementsByClassName(className):根据HTML元素的class名称找到该DOM对象的集合

④ document.getElementsByTagName(tagName):根据HTML元素的标签名找到该DOM对象的集合

⑤ document.querySelector(CSS选择器):通过CSS选择器返回DOM对象

示例:

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>demo34</title>

</head>

<body>

<div id="mdiv" style="border: 1px solid #ccc;"></div>

<input type="text" name="info" id="info">

<p id="mp">一个段落</p>

<script>

//找到 id=mdiv 的 dom 对象

let mdiv = document.getElementById("mdiv");

//设置 dom 对象的属性

/**

* dom 对象常用属性:

* innerHTML:获取或设置 dom 对象内部的 HTML 片段

* innerText:获取或设置 dom 对象内部的文本内容

*/

mdiv.innerHTML = "<h1>新增的h1标签</h1>";

//mdiv.innerText = "<h1>新增的h1标签</h1>";

//找到 info 这个 dom

var info = document.getElementById("info");

//设置 info 对象的 value 属性:

info.value = "我是通过 js 代码设置的 value 值";

/**

* 我们除了可以使用 dom 对象的原生属性之外,还可以通过 dom.setAttribute(属性名, 属性值) 来设置 dom 的属性值,通过

* dom.getAttribute(属性名) 来获取 dom 对象的属性值,并且该方式可以设置自定义的属性

*/

var mp = document.getElementById("mp");

mp.innerText = "我是通过 js 添加的文本";

//添加一个自定义属性

//mp.test = "测试";

mp.setAttribute("test","测试");

</script>

</body>

</html>

(3)利用节点关系访问 HTML 元素

① Node parentNode:返回当前节点的父节点

② Node previousNode:返回当前节点的前一个兄弟节点

③ Node nextSibling:返回当前节点的下一个兄弟节点

④ Node[] childNodes:返回当前节点的所有孩子节点

⑤ Node firstChild:返回当前节点的第一个孩子节点

⑥ Node lastChild:返回当前节点的最后一个孩子节点

示例:

(4)节点的修改:这里的修改我们主要指对元素节点的操作。

① 创建节点:document.createElement(标签名)

② 删除节点:父节点.removeChild(子节点)

③ 替换节点:父节点.replaceChild(新节点 , 旧节点)

④ 插入节点

父节点.appendChild(子节点)

父节点.insertBefore(新节点 , 旧节点)

示例:

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>demo57</title>

</head>

<body>

<div class="mf">

<!--javascript:void(0):禁用表单提交-->

<form action="javascript:void(0)" id="mf">

编号:<input type="text" name="id"> <br>

姓名:<input type="text" name="name"> <br>

年龄:<input type="text" name="age"> <br>

性别:<input type="text" name="sex"> <br>

工资:<input type="text" name="sal"> <br>

<input type="submit" value="增加">

</form>

</div>

<hr>

<div class="mt">

<table border="1" cellspacing="0" cellpadding="0" id="mt">

<thead>

<tr>

<th>编号</th>

<th>姓名</th>

<th>年龄</th>

<th>性别</th>

<th>工资</th>

<th>操作</th>

</tr>

</thead>

<tbody>

</tbody>

</table>

</div>

<script>

var myform = document.getElementById("mf");

var mytable = document.getElementById("mt");

//表单的提交事件:当表单提交的时候,执行后面的匿名函数

myform.onsubmit = function () {

//找到所有的 input 元素

let inputs = this.getElementsByTagName("input");

var id = inputs[0].value;

var name = inputs[1].value;

var age = inputs[2].value;

var sex = inputs[3].value;

var sal = inputs[4].value;

//通过表格对象找到 tbody 这个 dom 对象

let tbody = mytable.querySelector("tbody");

let tr = document.createElement("tr");//创建一个表格行

//表格行内容指定 HTML 片段

tr.innerHTML = "<td>"+id+"</td>" + "<td>"+name+"</td>" + "<td>"+age+"</td>" + "<td>"+sex+"</td>" +

"<td>"+sal+"</td>" + "<td><a href='javascript:void(0)'>删除</a></td>";

tbody.append(tr);//将包含了数据的表格行附加给 tbody 对象

//找到了当前行的最后一个孩子的孩子:就是"删除"这个 a 标签,给其添加一个单击事件

tr.lastChild.childNodes[0].onclick = function () {

//this在这里指的就是发生单击事件的 a 标签

this.parentNode.parentNode.remove();//将a的父元素的父元素 tr 本身删除

}

}

</script>

</body>

</html>

5.DOM 事件模型

(1)JavaScript 在浏览器中运行,浏览器中的 HTML 元素主要由 DOM 元素组成,这些 DOM 对象也会对应到各种 HTML 元素,我们可以为这些 DOM 对象添加事件处理函数,当某个 DOM 对象(HTML元素)发生对应的事件的时候,那么对应的事件函数就会自动被调用。

(2)HTML 元素的事件可以由事件属性来指定,事件属性是以事件类型加上一个 "on" 前缀来组成的,比如:onclick,onfocus 等等,这些属性名被称为事件处理器,属性值就是对应的事件处理函数,当事件发生时,对应的事件函数就自动被调用。

示例:

(3)绑定 DOM 对象的属性来绑定事件函数:

示例:找到某个 DOM 对象,给其事件属性指定事件函数

6.标准的 HTML 文档元素支持的事件:

示例1:变化表格的背景颜色

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>demo39</title>

<style>

*{

margin: 0;

padding: 0;

text-align: center;

}

.wrap {

width: 500px;

margin: 100px auto 0;

}

table{

border-collapse: collapse;/*单元格之间没有间距*/

border-spacing: 0; /*单元格之间间距为0*/

border: 1px solid #c0c0c0;

width: 500px;

}

th,td{

border: 1px solid #d0d0d0;

color: #404060;

padding: 10px;

}

th{

background-color: #09c;

font: bold 16px "微软雅黑";

color: #fff;

}

tbody tr{

background-color: #f0f0f0;

cursor: pointer;

}

.current {

background-color: red!important; /*不能继承父元素的颜色,必须为红色*/

}

</style>

</head>

<body>

<div class="wrap">

<table>

<thead>

<tr>

<th>序号</th>

<th>姓名</th>

<th>课程</th>

<th>成绩</th>

</tr>

</thead>

<tbody id="target">

<tr>

<td>1</td>

<td>吕不韦</td>

<td>语文</td>

<td>100</td>

</tr>

<tr>

<td>2</td>

<td>吕布</td>

<td>日语</td>

<td>100</td>

</tr>

<tr>

<td>3</td>

<td>吕蒙</td>

<td>营销学</td>

<td>100</td>

</tr>

<tr>

<td>4</td>

<td>吕尚</td>

<td>数学</td>

<td>100</td>

</tr>

<tr>

<td>5</td>

<td>吕雉</td>

<td>英语</td>

<td>100</td>

</tr>

<tr>

<td>6</td>

<td>吕超</td>

<td>体育</td>

<td>100</td>

</tr>

</tbody>

</table>

</div>

<script>

//各行变色

var tbody = document.getElementById("target");

var trArr = tbody.children;//找到 tbody 的所有孩子,即所有的 tr,不包含 td

for (let i = 0; i < trArr.length; i++) {

if(i % 2 == 0){

trArr[i].style.backgroundColor = "#a3a3a3";

}else {

trArr[i].style.backgroundColor = "#ccc";

}

//鼠标进入 tr 的时候高亮,离开后正常

var color = "";

//鼠标悬停修改 tr 背景色

trArr[i].onmouseover = function () { //给所有的 tr 绑定鼠标悬停事件

//在赋值之前,先记录原来的颜色

color = this.style.backgroundColor;//this 在这里指的是发生该事件的对象 tr

//将发生事件的 tr 的颜色修改

this.style.backgroundColor = "#fff";

}

//鼠标移出去的时候恢复原来的颜色

trArr[i].onmouseout = function () {

this.style.backgroundColor = color;

}

}

</script>

</body>

</html>

示例2:将左边 select 下拉框选中的元素移动到右边的 select 下拉框中

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>demo40</title>

<style>

select{

width: 170px;

height: 200px;

font-size: 16px;

background-color: #a4ff43;

}

</style>

</head>

<body>

<select name="sel1" id="sel1" size="10" multiple>

<option value="0">香蕉</option>

<option value="1">苹果</option>

<option value="2">鸭梨</option>

<option value="3">葡萄</option>

</select>

<button>>>></button>

<button><<<</button>

<button>></button>

<button><</button>

<select name="sel2" id="sel2" size="10" multiple>

</select>

<script>

//需求1:点击 <<< 和 >>> 按钮时,所有的子元素跑到对方标签中

var sel1 = document.getElementById("sel1");

var sel2 = document.getElementById("sel2");

var btnArr = document.getElementsByTagName("button");

btnArr[0].onclick = function () { //第一个按钮 >>>

//获取所有 sel1 的元素,整体添加到 sel2 中

var arr = sel1.children;

for (let i = arr.length - 1;i >= 0; i--){

sel2.appendChild(arr[i]);

}

}

//同理,全部过来

btnArr[1].onclick = function () { //第二个按钮 <<<

//获取所有 sel2 的元素,整体添加到 sel1 中

var arr = sel2.children;

for (let i = arr.length - 1;i >= 0; i--){

sel1.appendChild(arr[i]);

}

}

//需求2:点击 > 和 < 按钮时,选中的元素跑到对方,提示:option 有一个属性 selected,如果为 true,表示选中

btnArr[2].onclick = function () { //第三个按钮 >

//获取所有 sel1 的元素,选中的添加到 sel2 中

var arr = sel1.children;

for (let i = arr.length - 1;i >= 0; i--){

if (arr[i].selected === true)

sel2.appendChild(arr[i]);

}

}

btnArr[3].onclick = function () { //第四个按钮 <

//获取所有 sel2 的元素,选中的添加到 sel1 中

var arr = sel2.children;

for (let i = arr.length - 1;i >= 0; i--){

if (arr[i].selected === true)

sel1.appendChild(arr[i]);

}

}

</script>

</body>

</html>

7.DOM 事件模型

(1)DOM 也提供了事件模型:

通过 addEventListener('eventType',handler,captureFlag) 方法监听事件,其中 'eventType' 表示事件的名称,就是属性事件去掉 on 即可,handler 是事件函数,事件发生时触发,captureFlag 表示监听事件的阶段,true 表示捕获阶段,false 表示冒泡阶段,默认是 false。

示例:

(2)当事件发生时,会自动创建一个 Event 事件对象,并传递给事件函数作为参数,Event 接口中主要定义了如下属性:

① type:返回事件的类型,比如 click,mouseover 等等

② target:触发事件的事件源

③ currentTarget:返回事件当前所在的事件源

④ button:返回一个数字,代表出发事件的鼠标键,0 表示左键,1 表示中键,2 表示右键

⑤ altKey,ctrlKey,metaKey,shiftKey:分别代表事件发生时是否同时按下了alt,ctrl,meta,shift 键

⑥ clientX,clientY:返回事件发生时的鼠标的位置,以浏览器窗口为坐标系

⑦ screenX,screenY:返回事件发生时的鼠标的位置,以显示器为坐标系

⑧ offsetX,offsetY:返回事件发生时的鼠标的位置,以父元素作为坐标系

示例:

(3)事件传播

DOM 事件发生之后,会进行传播,会经历两个阶段,第一个阶段称为事件捕获阶段,事件从最顶层元素依次往下传播,直到传播到最底层元素,接着进入第二个阶段:事件冒泡阶段,事件传播从底层依次上溯,直到达到顶层的元素为止,如下图:

监听事件的函数 addEventListener() 方法的第三个参数可以指定是去监听捕获阶段(true),还是监听冒泡阶段(false,默认)。为了阻止事件传播,可以使用 Event 对象的 stopPropagation() 方法来阻止事件传播。

示例1:监听冒泡阶段(默认情况)

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>demo43</title>

<style>

*{

margin: 0;

padding: 0;

}

.p{

width: 400px;

height: 400px;

background-color: blue;

}

.s{

width: 300px;

height: 300px;

background-color: red;

}

.ss{

width: 200px;

height: 200px;

background-color: yellow;

}

</style>

</head>

<body>

<div class="p">

父 DIV

<div class="s">

儿子 DIV

<div class="ss">

孙子 DIV

</div>

</div>

</div>

<script>

var p = document.querySelector(".p");//父元素

var s = document.querySelector(".s");//子元素

var ss = document.querySelector(".ss");//孙子子元素

//addEventListener 默认情况下就是监听冒泡阶段

p.addEventListener("click",function () {

console.log("父元素被点击");

});

s.addEventListener("click",function () {

console.log("子元素被点击");

});

ss.addEventListener("click",function () {

console.log("孙子元素被点击");

});

</script>

</body>

</html>

从执行的结果可知,冒泡阶段事件传播的顺序是:孙子元素被点,然后是儿子元素,最后是父元素

示例2:监听捕获阶段

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>demo43</title>

<style>

*{

margin: 0;

padding: 0;

}

.p{

width: 400px;

height: 400px;

background-color: blue;

}

.s{

width: 300px;

height: 300px;

background-color: red;

}

.ss{

width: 200px;

height: 200px;

background-color: yellow;

}

</style>

</head>

<body>

<div class="p">

父 DIV

<div class="s">

儿子 DIV

<div class="ss">

孙子 DIV

</div>

</div>

</div>

<script>

var p = document.querySelector(".p");//父元素

var s = document.querySelector(".s");//子元素

var ss = document.querySelector(".ss");//孙子子元素

//addEventListener 第三个参数为 true 就是监听捕获阶段

p.addEventListener("click",function () {

console.log("父元素被点击");

},true);

s.addEventListener("click",function () {

console.log("子元素被点击");

},true);

ss.addEventListener("click",function () {

console.log("孙子元素被点击");

},true);

</script>

</body>

</html>

监听捕获阶段,事件传播的顺序:父元素,然后子元素,最后孙子元素

示例3:阻止事件传播:

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>demo43</title>

<style>

*{

margin: 0;

padding: 0;

}

.p{

width: 400px;

height: 400px;

background-color: blue;

}

.s{

width: 300px;

height: 300px;

background-color: red;

}

.ss{

width: 200px;

height: 200px;

background-color: yellow;

}

</style>

</head>

<body>

<div class="p">

父 DIV

<div class="s">

儿子 DIV

<div class="ss">

孙子 DIV

</div>

</div>

</div>

<script>

var p = document.querySelector(".p");//父元素

var s = document.querySelector(".s");//子元素

var ss = document.querySelector(".ss");//孙子子元素

//addEventListener 默认就是监听冒泡阶段

p.addEventListener("click",function () {

console.log("父元素被点击");

});

s.addEventListener("click",function () {

console.log("子元素被点击");

});

ss.addEventListener("click",function (e) {//e 就是 Event 对象

console.log("孙子元素被点击");

e.stopPropagation();//阻止事件传播

});

</script>

</body>

</html>

可以发现,当我们点击孙子元素时,只有孙子元素响应了事件,事件被阻止了,没有继续往上传播。

综合案例:祝愿墙

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>祝愿墙</title>

<style>

body {

margin: 0 auto;

padding: 0px;

font-size: 12px;

background: url("images/bg.gif") repeat center 36px;

text-align: center;

background-color: #c30230;

}

#content {

margin: 0 auto;

width: 960px;

background: url("images/content_bg.jpg") no-repeat left top;

height: 627px;

position: relative;

}

#content .tip0, #content .tip1, #content .tip2, #content .tip3, #content .tip4, #content .tip5, #content .tip6, #content .tip7, #content .tip8 {

position: absolute;

width: 227px;

left: 200px;

top: 100px;

}

#content .tip_h {

background: url("images/tip1_h.gif") no-repeat left top;

width: 227px;

padding-top: 45px;

height: 23px;

text-align: left;

cursor: move;

}

#content .tip_c {

background: url("images/tip1_c.gif") repeat-y;

width: 200px;

padding-left: 12px;

padding-right: 15px;

min-height: 40px;

text-align: left;

line-height: 20px;

max-height: 160px;

word-wrap: break-word; /*强制长单词在其容器宽度不足时自动换行*/

word-break: break-all; /*允许在单词内换行*/

overflow: hidden;

}

#content .tip_f {

background: url("images/tip1_f.gif") no-repeat left top;

width: 227px;

height: 53px;

padding-top: 20px;

}

#content .num {

float: left;

padding-left: 7px;

width: 195px;

}

#content .close {

float: left;

font-size: 12px;

cursor: pointer;

color: #000000;

}

.clr {

clear: both;

overflow: auto;

display: block;

height: 0px;

}

#content .icon {

float: left;

width: 35px;

padding-left: 15px;

height: 35px;

text-align: center;

}

#content .name {

float: right;

padding-right: 15px;

text-align: right;

font-size: 14px;

line-height: 35px;

color: #C0F;

}

</style>

</head>

<body>

<!--纸条墙-->

<div id="content">

</div>

<script>

//模拟数据库,获取信息

var messages = [

{"id":1,"name":"mahu","content":"今天你拿苹果支付了么","time":"2016-02-17 00:00:00"},

{"id":2,"name":"haha","content":"今天天气不错,风和日丽的","time":"2016-02-18 12:40:00"},

{"id":3,"name":"jjjj","content":"常要说的事儿是乐生于苦","time":"2016-03-18 12:40:00"},

{"id":4,"name":"9.8的妹纸","content":"把朋友家厕所拉堵了 不敢出去 掏了半小时了都","time":"2016-03-18 12:40:00"},

{"id":5,"name":"雷锋ii.","content":"元宵节快乐","time":"2016-02-22 12:40:00"},

{"id":6,"name":"哎呦哥哥.","content":"据说今晚央视的元宵晚会导演和春晚导演是同一个人,真是躲得过初一,躲不过十五。","time":"2016-02-22 01:30:00"},

{"id":7,"name":"没猴哥,不春晚","content":"班主任:"小明,你都十二岁了,还是三年级,不觉得羞愧吗"?。小明:"一点也不觉得,老师你都四十多岁了,不也是年年在三年级混日子吗?羞愧的应该是你"。老师:......","time":"2016-02-22 01:30:00"},

{"id":8,"name":"哎呦杰杰.","content":"真搞不懂你们地球人,月亮有什么好看的,全是坑,还是对面那哥们好看,","time":"2016-02-22 01:30:00"},

{"id":9,"name":"哎呦哎呦","content":"今天哪里的烟花最好看!!?答:朋友圈。。。","time":"2016-02-22 02:30:00"}

];

//需求1:模拟数据库获取信息,然后在页面上生成数组的长度个tip,然后分别填充内容。

//需求2:点击内容,提高层级;点击关闭按钮,删除tip标签;双击顶部,删除标签.....

//步骤:

//获取相关元素

var content = document.getElementById("content");

//循环生成div标签,然后为innerHTML属性添加内容

for(var i=0;i<messages.length;i++){

//生成新标签

var newDiv = document.createElement("div");

//绑定类名和ID

newDiv.className = "tip" + i;

newDiv.id = "tip" + messages[i].id;

//改变位置

var topValue = parseInt(Math.random()*400);

var leftValue = parseInt(Math.random()*700);

newDiv.style.top = topValue+"px";

newDiv.style.left = leftValue+"px";

//赋值内容

newDiv.innerHTML = '<div class="tip_h" title="双击关闭纸条">'+

'<div class="num">第[49568]条 '+messages[i].time+'</div>'+

'<div class="close" title="关闭纸条" >×</div>'+

'<div class="clr"></div>'+

'</div>'+

'<div class="tip_c">'+

messages[i].content +

'</div>'+

'<div class="tip_f">'+

'<div class="icon">'+

'<img src="images/bpic_1.gif" alt="" title="">'+

'</div>'+

'<div class="name">'+messages[i].name+'</div>'+

'<div class="clr"></div>'+

'</div>';

//把新创建的元素放入content里面

content.appendChild(newDiv);

//绑定事件,提高层级

var index = 1;

newDiv.onclick = function () {

this.style.zIndex = index;

index++;

};

//点击关闭按钮的时候关闭父盒子。

var closeDiv = newDiv.getElementsByClassName("close")[0];

closeDiv.onclick = function () {

//this就是 close这个div

content.removeChild(this.parentNode.parentNode);

}

//双击关闭按钮类名叫做tip_h

var dbDiv = newDiv.getElementsByClassName("tip_h")[0];

dbDiv.ondblclick = function () {

//this 就是值 tip_h

content.removeChild(this.parentNode);

}

}

</script>

</body>

</html>

九、AJAX

1、AJAX概述

(1)什么是Ajax ?

AJAX(Asynchronous JavaScript and XML)是一种能够让前端网页和后台Web服务器进行异步交互的技术,可以实现页面局部刷新(可以不用去加载整个页面而实现页面的局部刷新)。AJAX 的主要作用是让网页能与服务端进行数据异步交互,我们能够使用 HTML+AJAX 能够代替 JSP,实现网页上数据的动态展示。

(2)什么是异步交互?

异步交互是指能够让客户端发送一个请求后,不需要等待服务端的结果的返回,随时能够再次发送下一个请求。网页能够局部刷新就是利用了异步交互技术。而同步交互需要等待服务端响应数据后,才能发送下一个请求,所以使用同步交互的网页需要手动刷新。

(3)AJAX的优点:

1)提高网页的动态性。AJAX技术能让网页实现局部刷新,能够极大提高网页的动态性

2)提高用户体验。Ajax技术是一种异步交互技术,用户浏览器不必等待请求结果就能再次发送请求,大大提高用户体验,同时能够为用户提供搜索提示,验证提示

3)AJAX可使网页小程序更小、更快,更友好

2. 核心对象

XMLHttpRequest,AJAX 的所有操作都是通过该对象进行的

使用步骤:

(1)创建 XMLHttpRequest 对象

var xhr = new XMLHttpRequest();

(2)设置请求信息

//method表示请求后台服务器的方式:get或post等等方式,url:请求后台服务器的地址

xhr.open(method, url); //打开与后台服务器的连接

(3)发送请求

xhr.send(body)//get请求不传body参数,只有 post 请求要传 body

(4)接收响应

3. AJAX 快速入门:

(1)后台服务器:

基于 Servlet 的 Web 应用程序:Servlet 是部署在 HTTP 服务器(Tomcat服务器)的一个组件,专门用于响应用户的请求。

1)创建 JavaWeb 项目:

上面配置好的 Tomcat 是这样配置的

然后点击"下一步":

然后点击"Finish"就生成后台 Web 工程了,如下:

2)导入 gson.jar 包:

将后台的数据转换成前端能够接受的 JSON 数据,因为我们前后端交互使用 JSON 对象进行交互

a. WEB-INF 目录下新建 lib 目录,将 gson.jar 拷贝进去

b. 右键 lib 目录,将整个 lib 目录中的 jar 包添加为工程的库:Add As Library

3) 创建前后交互的 JavaBean:User

4) 创建后台组件 Servlet,跟前端进行交互

package com.edu.ctrl;

import com.edu.beans.User;

import com.google.gson.Gson;

import javax.servlet.ServletException;

import javax.servlet.annotation.WebServlet;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import java.io.IOException;

import java.io.PrintWriter;

import java.util.ArrayList;

import java.util.List;

@WebServlet("/userServlet") //该 Servlet 的后台 URL 地址

public class UserServlet extends HttpServlet {

//用于响应客户端的 GET 请求

@Override

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

//设置请求和响应的字符编码为 UTF-8,保证通讯过程中可以使用中文

request.setCharacterEncoding("UTF-8");

response.setContentType("text/html;charset=UTF-8");

//准备回送给客户端的数据

List<User> users = new ArrayList<>();

for (int i = 1; i <= 10; i++) {

users.add(new User(i, "姓名" + i, 20 + i, i%2==0?"男":"女"));

}

//产生 gson 对象,使用 gson 将 users 对象转换为 json 格式的字符串,发送给前端

Gson gson = new Gson();

String s = gson.toJson(users);//将 users 对象转换为 json 格式的字符串

PrintWriter out = response.getWriter();

out.write(s);//将 json 字符串写给客户端

out.flush();//刷新流

}

//用于响应客户端的 POST 请求

@Override

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

doGet(request, response);

}

}

(2) 在工程的 webapp 目录下创建前端页面 index.html

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>index</title>

</head>

<body>

<table border="1" cellspacing="0" cellpadding="0">

<thead>

<tr>

<th>编号</th>

<th>姓名</th>

<th>年龄</th>

<th>性别</th>

<th>操作</th>

</tr>

</thead>

<tbody>

</tbody>

</table>

<script>

//1. 创建 XMLHttpRequest 对象

var xhr = new XMLHttpRequest();

//2. 发送请求

//2.1 确定请求方式和请求后台的地址

xhr.open("GET","userServlet");

//2.2 发送请求到后台

xhr.send();

//3. 获取后台响应数据

xhr.onreadystatechange = function () {

//3.1 判断服务器端对于浏览器的请求是否响应完成,并判断客户端是否成功收到响应数据

if(this.readyState == 4 && this.status == 200){

//将服务器发送过来的JSON字符串转换为JavaScript的JSON对象

let users = JSON.parse(this.responseText);//得到的 users 是一个 json 对象组成数组

var content = "";

for (let i = 0; i < users.length; i++) {

content += "<tr>";//行

content += "<td>" + users[i].id + "</td>" +

"<td>" + users[i].name + "</td>" +

"<td>" + users[i].age + "</td>" +

"<td>" + users[i].sex + "</td>" +

"<td><a href=''>删除</a><a href=''>更新</a></td>";

content += "</tr>";

}

}

var tbody = document.querySelector("table tbody");

tbody.innerHTML = content;

}

</script>

</body>

</html>

(3) 部署 Web 应用程序到 Tomcat 服务器中运行:

然后部署应用:

然后点击启动按钮启动 Tomcat 服务器:

结果:

我们实现的是局部刷新,JS 代码只改动了表格的 tbody 部分,其他地方没有变,是属于异步的通讯方式,效率极高。

相关推荐
前端老鹰1 分钟前
JavaScript Intl.RelativeTimeFormat:自动生成 “3 分钟前” 的国际化工具
前端·javascript
梦想CAD控件2 分钟前
(在线CAD插件)网页CAD实现图纸表格智能提取
前端·javascript·全栈
sorryhc23 分钟前
【AI解读源码系列】ant design mobile——Space间距
前端·javascript·react.js
页面仔Dony1 小时前
绝对路径与相对路径的区别及作用
前端·javascript
林太白1 小时前
Zustand状态库(简洁、强大、易用的React状态管理工具)
前端·javascript·react.js
YuJie2 小时前
vue3 无缝滚动
前端·javascript·vue.js
晴空雨2 小时前
Emmet 完全指南:让 HTML/CSS 开发效率提升 10 倍
前端·html
小野鲜2 小时前
前端打开新的独立标签页面,并且指定标签页的大小,管理新标签页面的打开和关闭(包含源码和使用文档)
前端·javascript
十五_在努力2 小时前
参透 JavaScript —— 解析浅拷贝、深拷贝及手写实现
前端·javascript
王六岁2 小时前
JavaScript值和引用详解:从栈堆内存到面试实战
javascript·面试