前端开发(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 部分,其他地方没有变,是属于异步的通讯方式,效率极高。

相关推荐
用户102207917571111 分钟前
表格拖拽原生实现
前端·javascript
xyphf_和派孔明16 分钟前
web前端React和Vue框架与库安全实践
前端·javascript·前端框架
hqxstudying20 分钟前
前后端交流
java·css·后端·html·json
一只小风华~26 分钟前
JavaScript:Ajax(异步通信技术)
前端·javascript·ajax·web
一个很帅的帅哥1 小时前
JavaScriptAJAX异步请求:XHR、Fetch与Axios对比
javascript·axios·xmlhttprequest·fetch
十五_在努力2 小时前
参透 JavaScript —— 彻底理解 new 操作符及手写实现
前端·javascript
lwlcode3 小时前
前端大数据渲染性能优化 - 分时函数的封装
前端·javascript
coding随想3 小时前
HTML5插入标记的秘密:如何高效操控DOM而不踩坑?
前端·html
前端Hardy3 小时前
HTML&CSS:超丝滑抛物线飞入购物车效果
前端·javascript·css