Java全栈学习——前端JS

JavaScript简介

  JS可以为HTML页面添加动态效果,这种动态效果是通过规定好的事件触发的。这种动态的效果提高了网页的交互性。同时,AJAX技术使得页面可以异步加载,提高了页面的使用效率(这个后面会说)。
  总之,JS在整个前端中来说,是相对重要且和后端交互最多的一个部分。一定要牢牢掌握。
   和CSS一样,既然想为网页添加动态效果,其实本质上就是控制网页中的对应的标签所以,JS中也会有各种选择器。选择器用来选定某个标签,不同选择器的效率不同,我们需要按照开发的需求使用对应的选择器。所以你需要知道如何在H5页面中选中对应的标签——通过id、标签名和class,这一部分之前已经讨论过。

1. JS基础

  JS是一门编程语言,其代码的编写符合编程语言的规范,包括变量的声明、函数的编写和调用,控制语句(循环和分支)等。要注意的是:JS是弱类型语言,即在变量的声明时,不需要指定变量的类型,除此之外,其编写风格和Java基本类似。
  在编写JS代码的时候一定要学会灵活的使用IDE的代码提示功能!!

1.1 JS中的事件(Event)

概念

  开头提到了事件这一个概念,我的理解**就是JS规定的一些用户可做出的动作。最常见的我们单击某个按钮(input标签的bottom),这在JS看来就是一个事件。JS会捕捉当前页面上所发生的事件,并通过函数(function)**来造成某些效果。可以说JS就是一个事件驱动型的语言。
  如果你有通过编程语言操作文件的经历,你肯定知道,第一步就是获取文件的句柄,即在你的程序中,声明一个变量,这个变量在整个程序执行的过程中代表的就是这个文件,所以对这个变量的操作就等同于对文件的操作。同样的,在JS中也有类似的概念,**每个事件对应一个句柄,**通过在标签中声明某个句柄就可以获取这个事件,接着,浏览器就会监听当前页面,如果对应标签上发生了事件,那么就会获取到这个事件的句柄,然后去执行对应的代码。其过程如下:(图片来自这里
在这里插入图片描述

常见的JS事件

事件名称句柄
单击clickonclick
双击dbclickondbclick
获得焦点focusonfocus
失去焦点bluronblur

  通过句柄=“函数”的方式来为某个标签绑定上函数。例如<input type="button" value="click here" onclick="window.alert(123)"/>.

在这里插入图片描述

内置对象

  JS中我们常常需要用到一些内置对象,这些内置对象是浏览器生成的,直接提供给用户,方便我们操作。其关系如下:(图片源点击这
在这里插入图片描述
  常用的内置对象:

  • window:JS中,window指代当前浏览器的窗口。window.fucntion(parameters) window可以省略。
  • document:整个HTML页面,通过document可以获取当前页面的标签对象。
  • console:提供和控制台相关的方法,主要是方便我们调试和检查代码。

1.2 JS嵌入方式

  和CSS一样,在web开发中,JS也是为了增强HTML页面的能力的,所以如果想使用JS,就必须在HTML中嵌入JS代码,一般有三种方式:(和CSS基本一致)

  • 在标签的属性域绑定事件,并执行函数:<input type="button" value="click here" onclick="window.alert(123)"/>;
  • 在HTML页面中编写JS代码块;<script type="text/javascript"> 你的JS code </script>;
  • 引入独立的JS文件:<script scr="你的JS文件路径" type="text/javascript" charset="UTF-8"></script>
  • 示例: 代码块内部的代码会在页面一打开就执行,且可以写在任何位置
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>单击事件</title>
		<script src="my.js" type="text/javascript" charset="utf-8"></script>
	</head>
	<body>
		<input type="button" value="click here" onclick="window.alert('hello world')"/>
		<script type="text/javascript">
			alert(hello);
			alert(hello world);
		</script>
	</body>
</html>

1.3 定义变量

  在script标签体中定义:

  如果该变量没有赋值,那么就会赋值为undefined。

<script type="text/javascript">
	var age = 10;
    console.log(age);
</script>

1.4 JS的函数

  直接写在JS代码块的内容会被执行,不论是否由事件引发。所以,我们需要将由一些特定事件而引发的动作封装到函数中,再将函数与事件绑定。


Code

function hello() {
	window.alert(1234)
	window.alert('欢迎来到本站')
	}
function add(a,b) {
	c = a + b;
   alert(c);
}	
// 另一种函数声明方式
sayhello = function() {
    函数体
}
window.alert("这句话将会被直接调用");
var a = 10;
var b = 20;
var c = 0;

  有了函数,我们必须将其与对应的事件绑定才可以发挥作用,总的来说,JS事件绑定有两种方式:

  • 嵌入式绑定:<input type="botton" onclick="func()"/>
  • 基于DOM对象的绑定:通过选择器获取到一个DOM对象 dom1,用类似于声明的方式赋值:dom1.onclick=func1;

1.5 JS选择器

  和CSS一样,JS中也有选择标签的操作。之前说到的,每个标签都会被浏览器解析成唯一的对象,同时浏览器为我们提供了一个document对象,这个对象代表了当前的THML页面,所以我们可以通过这个对象来获取当前的页面的标签。通过getElementByXXX()或者getElementsByXXX() 的方式获取对象,在函数内部拿到了一个标签对象,那么我们就可以在JS函数里面对这个对象进行任何操作,包括修改标签的属性,为标签写入文本和HTML代码等。
在这里插入图片描述

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>获取HTML标签对象</title>
	</head>
	<body>
		<script type="text/javascript">
			function div1() {
				var div1 = document.getElementById("div1");
				console.log(div1);
			}
			
			function botton1() {
                // 获取标签
				var click = document.getElementById("botton1");
				console.log(click);
			}
			
			function text1() {
				var text1 = document.getElementById("text1")
				console.log(text1);
			}
		</script>
		
		<div id="div1" onmousedown="div1()">
			我是一个DIV
		</div>
		<input type="text" id="text1" value="" onfocus="text1()" />
		<input type="button" name="botton1" id="botton1" value="click" onclick="botton1()" />
	</body>
</html>

执行效果:
在这里插入图片描述

1.6 JS获取的标签对象

  通过get方法可以获取标签对象,这个对象提供了很多属性和方法,我们可以修改对应的属性和方法来达到对标签的控制。我们可以通过IDE 的代码提示来寻找需要的函数和属性,有两个常用的属性:

  • innerText:一个标签中修饰的文字部分,通过这个属性我们可以获取一个标签体的内容(返回的是string),也可以修改它。
  • innerHTML:和innerText基本上差不多,对这个属性进行修改时,修改的内容会被解析成HTML代码。
    一个案例:
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>innerText和innerHTML</title>
		<script>
			function show() {
				var div1 = document.getElementById("div1");
				console.log("通过innerText获取的div1的内容是"+div1.innerText);
				console.log("通过innerHTML获取的div1的内容是"+div1.innerHTML);
			}
			function change() {
				var div2 = document.getElementById("div2");
				var div3 = document.getElementById("div3");
				div2.innerHTML = "<font color='blue'>我是通过innerHTML改变的,我是蓝色的</font>";
				div3.innerText = "我是通过innerText改变的,我是白色";
			}
		</script>
	</head>
	<body>
		<div id="div1">
			我是一个div!
		</div>
		<input type="button" name="" id="" value="测试获取内容" onclick="show()" />
		<input type="button" name="" id="" value="测试修改内容" onclick="change()" />
		<div id="div2">
			我是一个div!
		</div>
		<div id="div3">
			我是一个div!
		</div>
	</body>
</html>

显示效果:


在这里插入图片描述
在这里插入图片描述在这里插入图片描述

2. jQuery

  JQuery可以理解为是JS的一种框架,基于JS,JQuery封装了JS对DOM对象的操作,使其简化且高效。
  学习JQuery主要有两点:

  • JQuery的选择器和过滤器;
  • JQuery提供的常用功能函数。

2.1 如何导入JQuery

  首先我们需要导入JQuery的源码:

<script src="https://s3.pstatp.com/cdn/expire-1-M/jquery/3.3.1/jquery.min.js"></script>

  这时候你就可以在你的HTML页面中编写JQuery代码了,当然你也可以导入独立的JQuery文件:

<script type="text/javascript" src="你的jquery文件位置"></script>

2.2 对象

  JQ对象绝对不是新的概念,他只是将DOM对象(JS操作的对象)封装起来使用,可以理解为JQ为我们开辟了数组,存储了我们要操作的DOM对象。

DOM对象

  1. 在HTML页面被加载时, 浏览器会创建出一个DOM树, 每个节点就是一个标签
  2. 一个DOM对象对应一个标签
  3. 我们通常对标签的操作本质上是调用DOM对象的某些方法,或者修改其属性
  4. 这就是为什么可以使用this关键字,因为本质上每个标签都是一个对象, this指向的就是当前标签这个对象

JQ对象

  1. 由JQuery函数创建$()
  2. 本质上是一个数组
  3. 存放着定位到的DOM对象
  4. 通过函数来操作这些对象
  5. Jquery对象的操作和数组完全一致, 支持[]操作,具有length属性, 实际上, 生成Jquery对象就是将DOM对象放入数组的过程.

2.3 JQ选择器

  选择器和CSS中的作用一样,是为了选择指定的标签,同时,过滤器从作用上也可以理解为是一种选择器,是通过过滤条件来选中标签对象。

基本选择器:

  1. $("#id编号"):相当于document.getElementById(“id”); 只选中一个元素,但是返回的是一个数组。
  2. $(".class") :相当于document.getElementByClassName(“class名称”); 根据类名来定位
  3. $("标签名") :相当于document.getElementsByTagName(“标签名”); 根据标签名来定位
  4. 支持按照正则表达式选择
  5. 组合选择器: $("条件1, 条件2"): 会获得多个标签
      除了基本选择器以外,其他选择器只在特定的场景比较好用。
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>JQ复习</title>
		<script src="https://s3.pstatp.com/cdn/expire-1-M/jquery/3.3.1/jquery.min.js"></script>
		<script type="text/javascript">
			function changeByJinghao() {
				var div1 = $("#div1");
				div1[0].innerHTML = "<font>我通过单击change1按钮发生改变</font>";
			}
			function changeByDian() {
				var eles = $(".div2");
				eles[0].innerHTML = "<font>我通过单击change2按钮发生改变</font>";
				eles[1].innerHTML = "<font>我通过单击change2按钮发生改变</font>";
			}
			function changeByLabelName() {
				var eles = $("span");
				eles[0].innerHTML = "<font>我通过单击change3按钮发生改变</font>";
				eles[1].innerHTML = "<font>我通过单击change3按钮发生改变</font>";
			}
			function changeByMulit() {
				var eles = $("#span1, #div3");
				eles[0].innerHTML = "<font>我通过单击change4按钮发生改变</font>";
				eles[1].innerHTML = "<font>我通过单击change4按钮发生改变</font>";
			}
		</script>
	</head>
	<body>	
		<div id="div1">我是div1</div>
		<input type="button" name="" id="" value="change1" onclick="changeByJinghao()"/>
		<div class="div2">我是div2</div>
		<div class="div2">我是div2</div>
		<input type="button" name="" id="" value="change2" onclick="changeByDian()"/><br>
		<span>我是一个span</span><br>
		<span>我也是一个span</span><br>
		<input type="button" name="" id="" value="change3" onclick="changeByLabelName()"/>
		<div id="div3">我是div3</div>
		<span id="span1">我是span1</span><br>
		<input type="button" name="" id="" value="change4" onclick="changeByMulit()" />
	</body>
</html>

Alt

层级选择器

  我们之前说过的,HTML页面会被解析成一棵DOM树,而树的最大特征就是有层级的关系,父子关系和兄弟关系。当需求要选中DOM树中某一层的节点,或者基于某个节点去寻找他的父或者子节点时,使用层级选择器的效率会很高。

可以根据标签之间的层级关系(父子,兄弟)来定位,因为HTML本质上是一颗dom树.
例如:
	<tr>
    	<td>
            <font id="f1"></font>
            <font id="f2"></font>
        </td>    
    </tr>
标签关系:
    1. 直接子标签: td是tr的子标签
    2. 间接子标签: font 是tr的间接子标签(孙子关系)
    3. 兄弟标签: 平行关系
		哥哥标签:f1是f2的哥哥

  使用方法:

  • $("定位父标签条件>定位子标签条件") :选择当前父标签下的所有满足条件的直接子标签。
  • $("定位父标签条件 定位子标签条件"):选择当前父标签下的所有满足条件的直接子标签,和间接子标签
  • $("定位当前签条件~定位兄弟签条件"):定位当前标签之后的满足条件的兄弟标签
  • $("定位当前签条件+定位兄弟签条件"):定位当前标签之后紧邻的的满足条件的兄弟标签
  • $("定位当前标签条件").siblings("定位兄弟标签条件"):定位当前标签所有满足条件的兄弟标签
  • $('#d1').next() :定位当前标签的后面一个兄弟标签
  • $('#d1').nextAll() :定位当前标签的后面所有兄弟标签
  • $('#d1').prev() :定位当前标签的前面一个兄弟标签
  • $('#d1').prevAll() :定位当前标签的前面所有兄弟标签
  • $('#d1').parent() :定位当前标签的直接父标签
    注意:以上所有的函数参数都可以传入基本选择器进行进一步筛选。
<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>JQ--层级选择器</title>
		<script src="https://s3.pstatp.com/cdn/expire-1-M/jquery/3.3.1/jquery.min.js"></script>
		<script type="text/javascript">
			function test1() {
				var elements = $("#fa1>font");
				var elements1 = $("#fa1>#fontt1");
				console.log(elements1[0]);
				for (var i = 0; i < elements.length; i++) {
					console.log("element"+i+"-----"+elements[i]);
					elements[i].color = "green";

				}
			}
			function test2() {
				var elements = $("#fa2 font");
				for (var i = 0; i < elements.length; i++) {
					console.log("element"+i+"-----"+elements[i]);
					elements[i].color = "green";

				}
			}
			function test3() {
				var elements = $("#fa3~div");
				for (var i = 0; i < elements.length; i++) {
					elements[i].style = "background-color:red";
				}
			}
			
			function test4() {
				var elements = $("h3+div");
				for (var i = 0; i < elements.length; i++) {
					elements[i].style = "background-color:green";
				}
			}
			function test5() {
				var elements = $("#fa3").siblings("div");
				for (var i = 0; i < elements.length; i++) {
					console.log(elements[i]);
				}
			}
		</script>
	</head>
	<body> 
		<!-- $("定位父标签条件>定位子标签条件")-->
		<div id="fa1">
			<font color="red" id="bro1">我是fa1————bro1</font><br>
			<font id="bro2">我是fa1————bro2</font>
			<div id="bro3"><font size="" color="red" id="fontt1">能定位到我吗</font></div><br>
		<input type="button" name="" id="" value="测试第一种方法" onclick="test1()" />
		</div>
		
		<!-- $("定位父标签条件 定位子标签条件") -->
		<div id="fa2">
			<font color="red" id="bro1">我是fa1————bro1</font><br>
			<font id="bro2">我是fa1————bro2</font>
			<div id="bro3"><font size="" color="red" id="fontt1">能定位到我吗</font></div><br>
		</div>
		<input type="button" name="" id="" value="测试第一种方法" onclick="test2()" />
		
		
		<h3>下面是兄弟标签的测试</h3>
		<div id="fa3">我是fa3标签</div>	
		<div id="fa4">我是fa4标签</div>	
		<div class="c1">我是fa5标签</div>	
		<div class="c1">我是fa6标签</div>	
		<!-- <div id="" style="border: 33px; bgcolor: antiquewhite;">
			234343
		</div> -->
		<!-- $("定位当前签条件~定位兄弟签条件") -->
		<input type="button" name="" id="" value="测试第三种方法" onclick="test3()" />
		
		
		<!-- $("定位当前签条件+定位兄弟签条件") -->
		<input type="button" name="" id="" value="测试第四种方法" onclick="test4()" />
		
		<!-- $("定位当前标签条件").siblings("定位兄弟标签条件") -->
		<input type="button" name="" id="" value="测试第五种方法" onclick="test5()" />
	</body>
</html>

显示效果:


在这里插入图片描述
在这里插入图片描述在这里插入图片描述
在这里插入图片描述

input标签选择器

  input标签作为接受用户输入的标签,在HTML的编写中起着重要的作用,JQ提供了对input标签的选择方法:$(":input标签的type属性")。例如:$(":button"),选中当前页面中所有的按钮。

2.4 JQuery的过滤器

  对已经放入JQ对象的标签进行二次的过滤。

基本过滤器:时刻记住JQ对象是一个数组

  • $("selector: first"): 在选出的JQ对象中,留下第一个DOM对象
  • $("selector: last"): 在选出的JQ对象中,留下最后一个DOM对象
  • $("selector: eq()"): 在选出的JQ对象中,留下指定下标的DOM对象
  • $("selector: lt()"): 在选出的JQ对象中,留下小于指定下标的DOM对象
  • $("selector: gt()"):在选出的JQ对象中,留下大于指定下标的DOM对象

属性过滤器:按照标签的属性来进行过滤

  • $("selector[attributions]") : 在选出的JQ对象中,留下指定属性赋值的DOM对象(如果没有手动为属性赋值,那么默认是空值)。
  • $("selector[attributions = 'value']") : 在选出的JQ对象中,留下指定属性赋指定值(value)的DOM对象
  • $("selector[attributions ^= 'value']") : 在选出的JQ对象中,留下指定属性的值以value开头的DOM对象
  • $("selector[attributions $= 'value']") :在选出的JQ对象中,留下指定属性的值以value结尾的DOM对象
  • $("selector[attributions *= 'value']") : 在选出的JQ对象中,留下指定属性的值包含value的DOM对象
      以上各种过滤方法都可以组合使用。

工作状态属性过滤器:本质上还是一个属性过滤器

  html标签属性分类:

  • 基本属性:绝大多数标签都拥有的属性———(id,name ,title,rowspan)
  • 样式属性:背景,字体,边框
  • value属性:只存在表单域标签中(input,select,textarea)
  • 工作状态属性:只存在表单域标签[chekced,disabled,selected]
  • 监听事件属性:onclick ,onchange,onfocus, onbulr
      基于工作状态属性,工作状态属性过滤器有:
  • $("selector:enabled"):在选出的JQ对象中,留下状态为enabled的DOM对象。
  • $("selector:disabled"):在选出的JQ对象中,留下状态为disabled的DOM对象。
  • $("selector:selected"):在选出的JQ对象中,留下状态为selected的DOM对象。
  • $("selector:chekced"):在选出的JQ对象中,留下状态为chekced的DOM对象。

2.5 JQuery常用函数

函数名功能案例
val()返回jq对象第一个元素的值$myobj.val()
val(“参数”)为JQuery对象中存储的所有DOM对象进行赋值
each(函数名)将传入的函数循环调用,每次读取一个下标值和下标对应的元素值each(myfunc) myfunc(index, element)
show(毫秒值)让Jquery元素在一定时间内显示出来${“div”}.show(300)
hide(毫秒值)让Jquery元素在一定时间内消失${“div”}.hide(300)
remove()删除当前标签的子标签${“div”}.empty()
remove()删除当前标签和子标签${“div”}.remove()
append(子标签)父标签调用, 给自己添加一个子标签${“#father”}.append(“son”)
appendTo()子标签调用, 给自己添加一个父标签${“son”}.appendTo(“father”)

2.6 JQuery的函数绑定

  除了使用JS提供的函数绑定方式,JQ也提供了一些绑定方式,且更加灵活。
注意:绑定事件的操作要么发生在中,要么就在HTML页面加载手动触发,即使用$(function() {绑定操作}),这样的方式来使得绑定生效。

通过监听事件绑定:

JQuery中重命名了事件,其规律是,把JS中的事件名称前的“on”去掉

JS监听的事件JQ监听的事件
onclick$obj.click(func)
onblur$obj.bulr(func)
onfocus$obj.focus(func)
onhandover$obj.handover(func)

通过bind的方式绑定:

  通过这种方式绑定可以解除,但是这种方式不可对动态的资源进行绑定,比如后来增加的内容就无法绑定上事件。
  语法格式:

  • JSObject.bind("JQuery事件名",处理函数);
  • JSObject.unbind(处理函数); 解绑指定函数。
  • JSObject.bind();解绑全部函数。

通过on的方式绑定:官方推荐

  从JQ 1.7之后,官方就推出on()和off()方法来实现事件的绑定和解绑。使用 on() 方法添加的事件处理程序适用于当前及未来的元素(比如JS在触发了事件后创建的新元素)。
语法格式:

  • $(selector).on(event,childSelector,data,function):绑定事件
参数描述
event必需。规定要从被选元素添加的一个或多个事件或命名空间。由空格分隔多个事件值,也可以是数组。必须是有效的事件。
childSelector可选。规定只能添加到指定的子元素上的事件处理程序(且不是选择器本身,比如已废弃的 delegate() 方法)。
data可选。规定传递到函数的额外数据。
function可选。规定当事件发生时运行的函数
  • $(selector).off(event,selector,function(eventObj),map):解绑事件
参数描述
event必需。规定要从被选元素移除的一个或多个事件或命名空间。由空格分隔多个事件值。必须是有效的事件。
selector可选。规定添加事件处理程序时最初传递给 on() 方法的选择器。
function(eventObj)可选。规定当事件发生时运行的函数。
map规定事件映射 ({event:function, event:function, …}),包含要添加到元素的一个或多个事件,以及当事件发生时运行的函数。
  • $(selector).one(event,data,function) : one() 方法为被选元素添加一个或多个事件处理程序,并规定当事件发生时运行的函数。当使用 one() 方法时,每个元素只能运行一次事件处理程序函数。
参数描述
event必需。规定添加到元素的一个或多个事件。由空格分隔多个事件值。必须是有效的事件。
data可选。规定传递到函数的额外数据。
function必需。规定当事件发生时运行的函数。

3. AJAX

3.1 基础知识

全局刷新:由页面发起的请求,只能发起一次。

  • 必须由浏览器发起页面请求
  • 发起的请求由服务器处理,响应回来的数据会存储在浏览器的内存中,并覆盖原有的内存
  • 所以,我们只能拿到响应的内容,而无法去显示被覆盖的内容。
    在这里插入图片描述
      局部刷新:一个页面有多个异步对象XMLHttpRequest),每个对象都可以向服务器发起请求:
  • 浏览器不发送请求
  • 请求将委托给异步对象发送请求,且服务器响应的内容也会被缓存到异步对象的内存中,并覆盖之前的内容;
  • 这使得其他没有被覆盖内容仍然可以正常显示。
    在这里插入图片描述  如何创建XMLHttpRequest对象呢?
	var xmlObj = new XMLHttpRequest();

  该对象存在于浏览器的内存中,隶属于某个页面。

3.2 什么是AJAX

  异步的JavaScript和XML. AJAX是一种技术方法,而不是编程语言。其核心是JS和XML。

  • JS负责创建异步对象,发送请求和更新DOM对象
  • XML是负责在客户端和服务器之间传输数据;现在多使用JSON(轻量,效率高)

  什么是异步?

  异步的概念来自操作系统:两个线程执行是相互独立, 即没有线程间通信.。

  一个浏览器可以创建多个线程(一个页面中), 这些线程有的是同步的(彼此之间有通信, 需要相互等待), 有的异步的.

  1. 使用AJAX可以在一个页面中发起多个请求, 提升加载速度。
  2. 使用AJAX可以实现局部刷新, 这样的当我们需要局部修改某些内容时, 就不用将整个页面都修改了( 转发 或者 重定向). 而且即使跳转回原来的页面, 也无法保存之前用户输入的东西, 比如在用户登录时, 用户名信息输入错误无法登录, 这种情况下, 跳转回login页面会把用户之前的东西清空, 这样用户体验差, 而且速度慢, 因为我们不需要全部刷新, 只需要提示用户名或者密码错误就好.

3.3 使用AJAX

  本质上就使用上文提到的异步对象。AJAX的使用有相对固定的步骤,熟练掌握这几个步骤就可以很轻松的学习。

属性描述
onreadystatechange存储函数(或函数名),每当 readyState 属性改变时,就会调用该函数。
readyState存有 XMLHttpRequest 的状态。从 0 到 4 发生变化。
0: 请求未初始化
1: 服务器连接已建立
2: 请求已接收
3: 请求处理中
4: 请求已完成,且响应已就绪
status
200: "OK"
404: 未找到页面

使用步骤为:

  • 创建异步对象:var xhr = new XMLHttpRequst()
  • 为异步对象绑定事件onreadystatechange
  • 按照不同的响应(readyState)做出不同的处理动作;
    xmlhttp.onreadystatechange=function()
      {
      // 在 onreadystatechange 事件中,我们规定当服务器响应已做好被处理的准备时所执行的任务。
      if (xmlhttp.readyState==4 && xmlhttp.status==200)
        {
        document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
        }
      }
    

readyState是如何变化的呢?

  • 0:初始创建对象 new XMLHttpRequest()
  • 1:初始异步请求对象,xhr.open()
  • 2:发送请求:xhr.send()
  • 3:从服务器端获取数据;
  • 4:异步对象处理完数据,交给我们使用,我们需要更新页面的内容。
      status 指你的当前的网络状态:
  • 200:请求成功
  • 404:页面找不到
  • 500:内部代码错误

  一个Demo:注意onreadystatechange 绑定的函数是通过回调的方式来调用的。当请求状态发生变化时,会自动调用这个函数。

<script type="text/javascript">
	function checkName() {
		var xhr;
        if (window.XMLHttpRequest) xhr = new XMLHttpRequest();
        else // ie5,6版本使用ActiveXObject来发送AJAX请求
        xhr = new ActiveXObject("Microsoft.XMLHTTP");

        xhr.onreadystatechange = function() {
			if(xhr.readyState == 4 && xhr.status == 200) {
				var text = xhr.responseText;x
				document.getElementById("nameTipsMsg").innerHTML = text;
			}
		}
		xhr.open("get","checkNameServlet?name='123'&password='abc'",true);
        xhr.send(); 
	}
</script>

以上面的demo为例:AJAX的执行顺序是:

  1. 首先执行open语句
  2. 接着使用send将AJAX请求发送给服务器;
  3. 如果服务器响应了,再回去执行onreadystatechange的绑定函数。

   open函数中第三个参数是决定本次请求是否是异步的:

  • true:异步处理请求。使用异步对象发起请求时,不用等待数据处理完毕就可以执行下面的代码。
  • false:同步处理请求。使用异步对象发起请求时,必须等待数据处理完毕才可以执行下面的代码。

AJAX常用的形式:

  上文提到的方式是AJAX原生的使用方式,也是最基础的内容。现在衍生了很多别的形式,在这里笔者指明一种常用的方式。但是从本质上上来说也是和原生方式使用的是差不多的。**而且原生方式方便我们学习和理解。**请仔细阅读各个参数,你会发现和原生方式一模一样。

$.ajax({
type: ["post","get"],
dataType: "html",
url: '/Resources/GetList.ashx',
data: dataurl,
success: function (data) {
}
});
error:function(data) {
}

3.4 AJAX案例:用户注册判断用户名是否重复:

  AJAX的编写需要和服务器进行交互,下面是笔者用来练习的一个案例,前提是你需要掌握:maven的使用、Javaweb基础、H5、JDBC。Maven是一种项目构建工具(会帮你导包和版本控制,建议掌握),如果你不会也不影响你的代码阅读,可以跳过这部分配置。
  如果你想复现这些内容,请修改数据库的配置和java代码中相关的包名。

Maven 仓库配置

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>javaweb-02-servlet</artifactId>
        <groupId>com.yr</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>

    <modelVersion>4.0.0</modelVersion>

    <artifactId>servlet-01</artifactId>
    <packaging>war</packaging>

    <name>servlet-01 Maven Webapp</name>
    <!-- FIXME change it to the project's website -->
    <url>http://www.example.com</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.9</maven.compiler.source>
        <maven.compiler.target>1.9</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.1</version>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/javax.servlet.jsp/jsp-api -->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.1</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

</project>

web.xml:

    <servlet>
            <servlet-name>Hello.do</servlet-name>
        <servlet-class>com.yr.servlet.UserNameCheckServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Hello.do</servlet-name>
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
    
    <welcome-file-list>
        <welcome-file>mytest.jsp</welcome-file>
    </welcome-file-list>

servlet: 一定要在web.xml中注册servlet,不然将无法向该servlet发送请求。

import javax.servlet.ServletException;
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.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class UserNameCheckServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        String reUserName = req.getParameter("username");
        PrintWriter out = resp.getWriter();
        System.out.println("进入了servlet");
        System.out.println(reUserName.toString());
        // 当用户名合法且没有重复时
        if (reUserName.length() < 14 && reUserName.length() > 4 && !BaseDao.function(reUserName)) {
                out.print("<font color='green'>用户名可用</font>");
        } else out.print("<font color='red'>用户名不可用</font>");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

数据库查询基类:请注意该类中的function并不规范,Javaweb的编写应当遵守MVC的分层思想,这里只是为了测试方便而已。

import java.sql.*;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;
public class BaseDao {
    public static String driver;
    public static String username;
    public static String password;
    public static String url;
    static {
        ResourceBundle resourceBundle = PropertyResourceBundle.getBundle("db");
        driver = resourceBundle.getString("driver");
        username = resourceBundle.getString("username");
        password = resourceBundle.getString("password");
        url = resourceBundle.getString("url");
        try {
        Class.forName(driver);
        } catch (ClassNotFoundException e) {e.printStackTrace();}
    }
    public static Connection getConnection() {
        Connection connection = null;
        try {
            connection = DriverManager.getConnection(url,username,password);
        } catch (SQLException throwables) {throwables.printStackTrace();}
        return connection;
    }

    public static boolean function(String username) {
        Connection connection = BaseDao.getConnection();
        String sql = "select id from smbms_user where userCode=?";
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        boolean flag = false;
        System.out.println("进入了function");
        try {
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setString(1,username);
            resultSet = preparedStatement.executeQuery();
            // 如果查到了内容就返回true。注意:返回true说明用户名重复了。
            return resultSet.next();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            if (resultSet != null) {
                try {
                    resultSet.close();
                } catch (SQLException throwables) {throwables.printStackTrace();}
            }

            if (preparedStatement != null) {
                try {
                    preparedStatement.close();
                } catch (SQLException throwables) {throwables.printStackTrace();
                }
            }

            if (connection != null) {
                try {
                    connection.close();
                } catch (SQLException throwables) {throwables.printStackTrace();}
            }
        }
        return false;
    }
}

JSP页面:

<%--
  Created by IntelliJ IDEA.
  User: 13918
  Date: 2020/9/27
  Time: 15:29
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>用户注册</title>
        <script src="https://s3.pstatp.com/cdn/expire-1-M/jquery/3.3.1/jquery.min.js"></script>
        <script type="text/javascript">
            //为输入框绑定失去焦点事件
            $(function() {
                $("#username").on( "blur", checkName);
            });
            //编写AJAX
            checkName =  function () {
                var obj = document.getElementById("username");
                var xmlhttp = new XMLHttpRequest();
                xmlhttp.onreadystatechange = function () {
                    if (xmlhttp.readyState == 4 && xmlhttp.status == "200") {
                        document.getElementById("nameTipsMsg").innerHTML = xmlhttp.responseText;
                    }
                }
                xmlhttp.open("get", "hello?username="+obj.value,true);
                xmlhttp.send();
            }
        </script>
    </head>

    <body>
        <center>
            <h3>User Register</h3>
            <form action="/s1/hello" method="get">
                <div align="center" id="userRegister">
                    <div align="center">
                        <center><div id="nameTipsMsg"></div></center><br>
                        <label>username:</label>
                        <input type="text" name="username" id="username" value="" placeholder="请输入用户名"/>
                    </div>
                    <br>
                    <div align="left">
                        <label>password:</label>
                        <input type="text" name="password" id="password" value="" placeholder="请输入密码"/>
                    </div><br>
                    <input type="submit" value="提交" />
                </div>
            </form>
        </center>
    </body>
</html>

显示效果:


在这里插入图片描述

4. JSON

  JSON现在是最常用的数据交换格式。是以Key-Value的形式存储的。JSON主要包括:

  • JSON对象:{name:"李四"}
  • JSON数组:[{name:"李四", age:12}, {name:"王五",age:123},{name:"赵柳",age:1323}]
    &esmp;&esmp;为什么要用JSON呢?
  • 阅读直观;
  • 在Java和JS中读写JSON格式很方便,且JSON文件比较小,传输快。
    &esmp;&esmp;处理JSON的工具库:gson,fastjson,jackson。

4.1 使用JSON

导入对应的JSON工具包:

package com.yr.servlet;
import com.fasterxml.jackson.core.JsonProcessingException;
import  com.fasterxml.jackson.databind.ObjectMapper;
class Person {
    String name;
    int age;

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
public class testJson {
    public static void main(String[] args) throws JsonProcessingException {
        Person person = new Person();
        ObjectMapper om = new ObjectMapper();
        // 将java对象转化成JSON对象
        String s = om.writeValueAsString(person);
        System.out.println("json---->"+s);
    }
}

结果:


在这里插入图片描述


  在JS中可以使用eval()将servlet返回的JSON字符串转化成JSON对象,JSON对象的名就是JSON对象的Key
  如果你使用的是JQuery,那么可以使用:var obj = jQuery.parseJSON(ret);方式来处理JSON文件。

4.2 案例:

下面是一个小的DEMO:利用AJAX搜索用户信息。

页面信息:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>JSON练习</title>
    <script src="https://s3.pstatp.com/cdn/expire-1-M/jquery/3.3.1/jquery.min.js"></script>
    <script type="text/css">
        #showInfo {
            float: left;
        }
    </script>
    <script type="text/javascript">
        findInfo = function () {
            var xmlthttp = new XMLHttpRequest();
            var idObj = document.getElementById("userId");
            var tips = document.getElementById("Tips");
            var elements = $("#name,#password");
            if (idObj.value == "") {
                tips.innerHTML = showText("输入不可以为空","5","red");
                for (var i = 0; i < elements.length; i++) elements[i].setAttribute("value","");
                return;
            }
            xmlthttp.onreadystatechange = function () {
                if (xmlthttp.readyState == 4 && xmlthttp.status == 200) {
                    var ret = xmlthttp.responseText; 
                    var obj = jQuery.parseJSON(ret);
                    if (obj == null) {
                        tips.innerHTML = showText("您查找的信息不存在","5","red");
                        for (var i = 0; i < elements.length; i++) elements[i].setAttribute("value","");
                        return;
                    }
                    tips.innerHTML = showText("您查找的信息如下:","3","green");
                    elements[0].setAttribute("value", obj.name);
                    elements[1].setAttribute("value", obj.password);
                }
            }
            xmlthttp.open("get", "JSONTest?id="+idObj.value,true);
            xmlthttp.send();
        }
        showText=function (info, size, color) {
            return "<font size='"+size+"' color='"+color+"'>"+info+"</font>";
        }
    </script>
</head>
<body>
        <div>
            <input type="text" name="id" id="userId"/>
            <input type="button" id="find" value="search" onclick="findInfo()"/>
        </div>
        <div id="showInfo">
            <div id="Tips"></div>
            用户名:<input class="info" id="name" /><br>
            密码:&emsp;<input class="info" id="password" />
        </div>

</body>
</html>

    <servlet>
        <servlet-name>JSONTest</servlet-name>
        <servlet-class>com.yr.servlet.JSONTestServlet</servlet-class>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>JSONTest</servlet-name>
        <url-pattern>/JSONTest</url-pattern>
    </servlet-mapping>

Servlet内容:

package com.yr.servlet;

import com.fasterxml.jackson.databind.ObjectMapper;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

import static java.lang.Class.forName;

public class JSONTestServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/json; charset=utf-8");
        User user = BaseDao.function1(req.getParameter("id"));
        ObjectMapper objectMapper = new ObjectMapper();
        String s = objectMapper.writeValueAsString(user);
        resp.getWriter().print(s);
    }
}

BaseDao:查找数据库的内容。

package com.yr.servlet;


import java.sql.*;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;

/**
 *
 */
public class BaseDao {

    public static String driver;
    public static String username;
    public static String password;
    public static String url;

    static {
        ResourceBundle resourceBundle = PropertyResourceBundle.getBundle("db");
        driver = resourceBundle.getString("driver");
        username = resourceBundle.getString("username");
        password = resourceBundle.getString("password");
        url = resourceBundle.getString("url");
        try {
            Class.forName(driver);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    public static Connection getConnection() {
        Connection connection = null;
        try {
            connection = DriverManager.getConnection(url,username,password);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return connection;
    }
    
    public static User function1(String id) {
        Connection connection = BaseDao.getConnection();
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        String sql = "select userName, userPassword from smbms_user where id=?";
        try {
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setString(1,id);
            resultSet = preparedStatement.executeQuery();
            if (resultSet.next()) {
                return new User(resultSet);
            }
        } catch (Exception throwables) {
            throwables.printStackTrace();
        } finally {
            closeResource(connection,preparedStatement,resultSet);
        }
        return null;
    }
    public static boolean closeResource(Connection connection, PreparedStatement preparedStatement, ResultSet resultSet) {
        boolean flag = true;
        if (resultSet != null) {
            try {
                resultSet.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
                flag = false;
            }
        }

        if (preparedStatement != null) {
            try {
                preparedStatement.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
                flag = false;
            }
        }

        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
                flag = false;
            }
        }
        return flag;
    }
}

User类:

package com.yr.servlet;
import java.sql.ResultSet;
import java.sql.SQLException;
public class User {
    String name;
    String password;
    public User() {}
    public User(ResultSet resultSet) {
        try {
            setName(resultSet.getString("userName"));
            setPassword(resultSet.getString("userPassword"));
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getPassword() {
        return password;
    }

}

效果展示:


在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值