4.事件驱动编程

本文深入介绍了事件驱动编程的概念,包括事件源、事件名称、事件响应函数和事件对象。接着讲解了三种事件绑定方法,并提供了实例。接着讨论了AJAX的核心技术和其优缺点。此外,文章还涉及了获取服务端时间、账号存在性检查、用户登录操作、二级联动的实现,以及JSON数据格式和处理库的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一.事件驱动编程

  1. 事件驱动编程

    • 所谓事件驱动,简单地说就是你点什么按钮(即产生什么事件),电脑执行什么操作(即调用什么函数).当然事件不仅限于用户的操作. 当对象处于某种状态时,可以发出一个消息通知,然后对这个消息感兴趣的程序就可以执行。
  2. 事件驱动编程中的几个核心对象

    • 事件源:谁发出事件通知,发出消息;也就是事件主体(通常指元素和标签);
    • 事件名称:发出什么样的通知的名称,比如鼠标到我头上了,我被别人点了一下;
    • 事件响应函数:谁对这个这个事件感兴趣,当这个事件发生时要执行什么样的操作;
    • 事件对象:一般来说,当事件发生时,会产生一个描述该事件的具体对象,包括具体的参数等一起发给响应函数,好让他们通过事件对象来了解事件更加详细的信息。

二.事件绑定

事件监听,也就是指对指定对象的指定事件指定响应处理处理函数;

  1. 第一种:
    在标签上使用onclick属性配置

    事件源: 点我呀这个button, 可以在调用响应函数中传入this获取
    事件名称:onclick
    响应函数:clickMe
    事件对象:可以在响应函数中传入event获取
    

    注意: 此方式无法重复绑定响应函数

  2. 第二种:
    在js代码中,使用 "元素.οnclick=响应函数"进行事件监听

  3. 第三种:
    使用方法来完成对元素的监听

    IE
        [Object].attachEvent(“name_of_event_handler”, fnHandler);
          name_of_event_handler : 事件名称: 注意:事件操作前,必须加"on"!!!
          fnHandler: 响应函数
          多次添加监听后,触发顺序: 先添加,后执行
                      
        [Object].detachEvent(“name_of_event_handler”, fnHandler);
            fnHandler : 移除时,传入的"事件响应函数",必须和添加时,传入的是同一个(通过相同标识符引用的那一个函数)
            匿名函数,每次创建的都不同	
      W3C
        [Object].addEventListener(“name_of_event”, fnHandler);
             name_of_event: 事件名称:  直接使用事件(操作)名称 (没有  on)
             多次添加监听后,触发顺序: 先添加,先执行           
             fnHandler: 响应函数
    
        [Object].removeEventListener(“name_of_event”, fnHandler);
            fnHandler : 移除时,传入的"事件响应函数",必须和添加时,传入的是同一个(通过相同标识符引用的那一个函数)
            匿名函数,每次创建的都不同
    
  4. 定义一个通用的添加事件的函数

function addListener(element,eventName,eventFn){
         if(element.attachEvent){
               element.attachEvent("on"+eventName,eventFn);
         }else{
               element.addEventListener(eventName,eventFn);
         }
}

事件对象中包括了事件源及事件的具体描述信息,一般包括事件源,鼠标事件或键盘事件的相关信息;在监听函数中有时候需要通过事件对象来获取更详细的事件信息,然后再进行处理

oDiv.onclick = function (oEvent) {
//参数oEvent即为事件对象
}

实例.
index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="indext.js"></script>
<title>Insert title here</title>
</head>
<body>
<!-- 用户触发按钮之后,js引擎自动创建event对象 -->
	<button onclick="onclickMe(this,event)" id="btn">方式1:点我呀</button><br>
	<button id="btn2">方式二.点我呀</button><br>
	<button id="btn3">方式三.点我呀</button><br>
</body>
</html>

index.js



//方式二:
window.onload=function (){
	//方式二,通过js代码方式指定事件
	var btn2 = document.getElementById("btn2");
	//事件源:btn2,在匿名的function中,打印的this就是事件源,没有srcEl这个参数
	//事件名称:onclick
	//相应函数:匿名funcion
	btn2.onclick=function(event){
		console.log(event);
		//console.log(srcEl);//不存在
		console.log(this);
		alert("我又被点了~~");
	};
	//方式2,事件无法重复绑定,如果重复绑定,后面的会覆盖前面的
	btn2.onclick=function(event){
		console.log(event);
		//console.log(srcEl);//不存在
		console.log(this);
		alert("我又又被点了~~");
	};
	
	//方式三:
	  
	/*//IE:
	var btn3= document.getElementById("btn3");
	//事件源:btn3
	//事件名称:attachEvent方法的第一个参数
	//响应函数:匿名函数function
	//事件对象:匿名function的第一个参数
	//参数1:事件名称
	//参数2:响应函数
	btn3.attachEvent("onclick",function(eventObject){
		alert("我怎又又被点击");
		console.log(eventObject);//event
		console.log(this);//window
	});
	//可以重复绑定,倒序执行
	btn3.attachEvent("onclick",function(eventObject){
		alert("我怎又又被点击");
		console.log(eventObject);//event
		console.log(this);//window
	});*/
	
	
	/*//W3C
	var btn3= document.getElementById("btn3");
	//方式三:
	//事件源:btn3,匿名function 内部this
	//事件名称:addEventListener方法的第一个参数
	//响应函数:function
	//事件对象:匿名function第一个参数
	//参数1:事件名称 点击事件(onclick)
	btn3.addEventListener("click",function(eventObject){
		alert("我怎又又被点击");
		console.log(this);//window
		console.log(eventObject);//
	});
	//可以重复绑定,顺序执行
	btn3.addEventListener("click",function(eventObject){
		alert("我怎又又被点击");
		console.log(this);//
		console.log(eventObject);//
	});*/
	
	
	//通用事件绑定
	addEvent(btn3,"click",function(){
		alert("我怎又又又被点击");
	});
};

//设计一个方法:统一事件的绑定,既可以绑定IE,又可以实现W3C绑定
/**
 * 
 * @param srcEl: 事件源
 * @param eventType: 事件名称,IE拼接on
 * @param fnHandler: 统一处理函数
 * @returns
 */

function addEvent(srcEl,eventType,fnHandler){
	//attachEvent 方法是IE方法,如果有值就是IE浏览器,反之就是W3C
	if(srcEl.attachEvent){//IE
		srcEl.attachEvent("on"+eventType,fnHandler);
	}else{//W3C
		srcEl.addEventListener(eventType,fnHandler);
	}
}


//方式1:在onclick属性设置事件
//事件源: 点我呀这个button,可以在相应函数中传入this获取
//时间名称:onclick 点击事件
//事件处理函数: onclickMe
//事件对象:可以在相应函数中传入event获取
function onclickMe(srcEl,event){
	//根据id获取事件源
	console.log(document.getElementById("btn"));
	//根据this获取事件源
	console.log(srcEl);
	console.log(this);
	console.log(event);
	//函数中自带的参数对象,用来包装调用者传入的参数
	console.log(arguments);
	alert("你真点啊!");
}

三.事件相关

image

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script type="text/javascript" src="indext.js"></script>
<title>Insert title here</title>
</head>
<body>
<img alt="" src="01.gif" id="myImg">
</body>
</html>

index.js

window.onload=function(){
	var imgEl = document.getElementById("myImg");
	
	addEvent(imgEl,"mouseout",function(){
		imgEl.src="01.gif";
	});
	addEvent(imgEl,"mouseover",function(){
		imgEl.src="02.gif";
	});
	
	addEvent(imgEl,"click",function(){
		imgEl.src="03.gif";
	});
	
};

//设计一个方法:统一事件的绑定,既可以绑定IE,又可以实现W3C绑定
/**
 * 
 * @param srcEl: 事件源
 * @param eventType: 事件名称,IE拼接on
 * @param fnHandler: 统一处理函数
 * @returns
 */

function addEvent(srcEl,eventType,fnHandler){
	//attachEvent 方法是IE方法,如果有值就是IE浏览器,反之就是W3C
	if(srcEl.attachEvent){//IE
		srcEl.attachEvent("on"+eventType,fnHandler);
	}else{//W3C
		srcEl.addEventListener(eventType,fnHandler);
	}
}

四.综合练习

多选框的选择
checkbox.html

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>checkbox</title>
<script type="text/javascript"  src="checkbox.js" ></script>
</head>
<body>
	请选择你的爱好:<br/>
	<input type="checkbox" onchange="checkChange(this)" id="checkAll"/>全选/全不选<br/>
	<div>
		<input type="checkbox" name="hobby"/>JAVA&nbsp;
		<input type="checkbox" name="hobby"/>打篮球&nbsp;
		<input type="checkbox" name="hobby"/>上网&nbsp;
		<input type="checkbox" name="hobby"/>撩妹&nbsp;
	</div>
	
	<div>
		<input type="button" id="btn_checkAll" onclick="checkAll(true)" value="全选"/>
		<input type="button" onclick="checkAll(false)" value="全不选"/>
		<input type="button" onclick="checkUnAll()" value="反选"/>
	</div>
</body>
</html>

checkbox.js

//全选/全不选
function checkAll(value){
	//1.获取全部hobby
	var hobbys = document.getElementsByName("hobby");
	//2.遍历所有
	for(var i = 0;i < hobbys.length; i++ ){
		hobbys[i].checked=value;
	}
};
//反选
function checkUnAll(){
	//1.获取全部hobby
	var hobbys = document.getElementsByName("hobby");
	for(var i = 0;i < hobbys.length; i++){
		hobbys[i].checked=!hobbys[i].checked;
	}
};
//全选/全不选
//srcEl 页面传进来的事件源
function checkChange(srcEl){
	//1: 获取上面id为checkAll多选框 状态
	//2:获取所有要勾选多选框
	//3:遍历这些多选框,改变他们的值
	
	//为true是表示全选,为false时为全不选
	checkAll(srcEl.checked);
};

select移动

select.html

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>选择列表</title>
<script type="text/javascript"  src="select.js" ></script>
</head>
<body>
	<table border="1">
		<tr>
			<td>
				<select id="select1" style="width:100px;height:200px" size="10" multiple="multiple">
					<option value="选项1">选项1</option>
					<option value="选项2">选项2</option>
					<option value="选项3">选项3</option>
					<option value="选项4">选项4</option>
					<option value="选项5">选项5</option>
					<option value="选项6">选项6</option>
					<option value="选项7">选项7</option>
					<option value="选项8">选项8</option>
					<option value="选项9">选项9</option>
				</select>
			</td>
			<td align="center">
				<input type="button" onclick="moveSelected('select1','select2')" value="-->"/><br/>
				<input type="button" onclick="moveAll('select1','select2')" value="==>"/><br/>
				<input type="button" onclick="moveSelected('select2','select1')" value="<--"/><br/>
				<input type="button" onclick="moveAll('select2','select1')" value="<=="/>
			</td>
			<td>
				<select id="select2" style="width:100px;height:200px" size="10" multiple="multiple"></select>
			</td>
		</tr>
	</table>
</body>
</html>

select.js

//全部移动
function moveAll(srcId,targetId){
	//1:获取源select的所有option
	var srcId=document.getElementById(srcId);
	var ops = srcId.children;
	//2:所有option添加到目标
	var targetId = document.getElementById(targetId);
	//一个一个往里面塞,不能一次性移动
	/*for(var i = 0;i < ops.length;i++){
		targetId.appendChild(ops[i]);
	}*/
	//当options有值的时候一直移动索引为0这个值
	while(ops.length>0){
		targetId.appendChild(ops[0]);
	}
}

//选中移动
function moveSelected(srcEl,targetEl){
	var srcEl = document.getElementById(srcEl);
	//选中的options
	var ops = srcEl.selectedOptions;
	var targetEl = document.getElementById(targetEl);
	//当options有值的时候一直移动索引为0这个值
	while(ops.length>0){
		targetEl.appendChild(ops[0]);
	}
}

user添加与删除

user.html

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>用户新增</title>
<script type="text/javascript"  src="user.js" ></script>
</head>
<body>
	<form name="userForm">
		<center>
			用户录入<br/>
			用户名:<input id="username" name="username" type="text" size=15/>
			E-mail:<input  id="email" name="email" type="text"  size=15/>
			电话:<input id="tel" name="tel" type="text" size=15/>
			<input type="button" value="添加" id="btn_submit"/>
			<input type="button" value="删除所有" id="btn_removeAll"/>
		</center>
	</form>
	<hr/>
	<table border="1" align="center" cellpadding=0 cellspacing=0 width=400> 
		<thead>
			<tr>
				<th>用户名</th>
				<th>E-mail</th>
				<th>电话</th>
				<th>操作</th>
			</tr>
		</thead>
		<tbody id="userTbody">
			<tr id="0001">
				<td>张无忌</td>
				<td>wujizhang@163.com</td>
				<td>18212345678</td>
				<td><a href="javascript:delRow('0001')">删除</a></td>
			</tr>
		</tbody>
	</table>
	
	
</body>
</html>

user.js

window.onload=function (){
	//1:获取添加按钮
	var addBtn= document.getElementById("btn_submit");
	//2:绑定一个点击事件
	addBtn.onclick=function(){
		//1.获取name,email,tel值
		var nameV=document.getElementById("username").value;
		var emailV=document.getElementById("email").value;
		var telV=document.getElementById("tel").value;
		
		//2.创建出相关的元素 tr/td
		var trEl = document.createElement("tr");
		//使用当前时间的毫秒数做id
		var idV = new Date().getTime();
		trEl.id=idV;
		var nameEl = document.createElement("td");
		var eamilEl = document.createElement("td");
		var telEl = document.createElement("td");
		var opEl = document.createElement("td");
		
		//设置td的内容
		nameEl.innerHTML = nameV;
		eamilEl.innerHTML = nameV;
		opEl.innerHTML = nameV;
		opEl.innerHTML="<a href='javascript:delRow(\""+idV+"\")'>删除</a>";
		
		//3.设置tr td tbody的关系
		trEl.appendChild(nameEl);
		trEl.appendChild(eamilEl);
		trEl.appendChild(telEl);
		trEl.appendChild(opEl);
		
		var tbody= document.getElementById("userTbody");
		tbody.appendChild(trEl);
	};
	
	//删除所有的按钮
	var removeAllBtn= document.getElementById("btn_removeAll");
	removeAllBtn.onclick=function(){
		var tbody=document.getElementById("userTbody");
		//把tbody的内容为空字符串
		tbody.innerHTML="";
	};
};


//定义删除行的方法

function delRow(trId){
	var trEl = document.getElementById(trId);
	//找到父类删除自己
	trEl.parentNode.removeChild(trEl);
}


五.AJAX

概述

  1. Ajax不是一项具体的技术,而是几门技术的综合应用。
    Javascript、XHTML和CSS、DOM、XML和XMLHttpRequest。
  2. Ajax核心只不过是要在javascript中调用一个叫XMLHttpRequest类,这个类可以与Web服务器使用HTTP协议进行交互,程序不通过浏览器发出请求,而是用这个特殊的JavaScript对象发送请求和接收响应。
  3. XMLHttpRequest对象在网络上的俗称为Ajax对象。
  4. 一种不用刷新整个页面便可与服务器通讯的办法(更新网页部分数据).

AJAX缺陷:

  1. AJAX大量使用了Javascript和AJAX引擎,而这个取决于浏览器的支持。IE5.0及以上、Mozilla1.0、NetScape7及以上版本才支持,Mozilla虽然也支持AJAX,但是提供XMLHttpRequest的方式不一样。所以,使用AJAX的程序必须测试针对各个浏览器的兼容性。
  2. AJAX更新页面内容的时候并没有刷新整个页面,因此,网页的后退功能是失效的;有的用户还经常搞不清楚现在的数据是旧的还是已经更新过的。这个就需要在明显位置提醒用户“数据已更新”。
  3. 对流媒体的支持没有FLASH、Java Applet好。 HTML5
  4. Ajax不支持跨域访问

六.获取服务端的时间-后台

先搭建java web项目结构

需要jar包

image

后台

mvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="
		   http://www.springframework.org/schema/context
		   http://www.springframework.org/schema/context/spring-context.xsd
           http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/mvc
           http://www.springframework.org/schema/mvc/spring-mvc.xsd">
           <!-- IoC注解解析器-->
    <context:component-scan base-package="cn.dusk"/>
    <!-- DI注解驱动器 -->
	<context:annotation-config/>
    <!-- 注解驱动器 -->
	<mvc:annotation-driven/>
	<!-- 视图解析器 -->
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="prefix" value="/WEB-INF/views/"/>
		<property name="suffix" value=".jsp"/>
	</bean>
</beans>

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
    <!--过滤器-->
    <filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>


    <!--配置SpringMVC的前端控制器-->
    <servlet>
        <servlet-name>mvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:mvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>mvc</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>
    
    
</web-app>

GetTimeController类

@Controller
public class GetTimeController {
	
	@RequestMapping("getTime")
	public void getTime(HttpServletResponse response) throws Exception {
		response.setContentType("text/html;charaset=utf-8");
		Date date = new Date();
		response.getWriter().write(date.toLocaleString());
	}
}

前端

index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="index.js"></script>
</head>
<body>
北京时间:<span id="sp">暂时没有时间</span><br>
<button id="getTime">获取系统时间</button>
</body>
</html>

index.js

window.onload=function(){
	var btn = document.getElementById("getTime");
	btn.onclick=function(){
		//使用ajax的请求获取系统当前时间
		
		//1.创建一个ajax对象
		var ajax = createAjax();
		//2.创建一个http请求对象
		/**
		 * 参数1:http请求方式 get post
		 * 参数2:http请求url
		 * 参数3:是否为异步请求 默认true
		 */
		//解决浏览器缓存的问题
		ajax.open("get","/getTime.do?time"+ new Date().getTime(),true);
		
		//3. 绑定htttp状态改变的监听器,处理请求结果
		ajax.onreadystatechange=function(){
			//当readState等于4的时候,表示数据请求已经回来了,
			//通知浏览器处理数据,进而改变页面元素的值
			//此时ajax提供一种状态改变机制,当readState状态为4时,表示ajax返回完毕
			//并且能正常返回数据的时候,才进行操作
			var sp = document.getElementById("sp");
			if(ajax.readyState == 4 && ajax.status == 200){
				sp.innerHTML=ajax.responseText;
			}else{
				sp.innerHTML="亲,网络繁忙,请稍后访问~~";
			}
		}
		//4:发送http请求 参数表示传递post 才使用的
		ajax.send();
	};
};

//通用的ajax对象创建
function createAjax(){
	var jaax = null;
	try{
		ajax = new XMLHttpRequest();
	}catch(e){
		ajax = new ActiveXObject("Microsoft.XMLHTTP"); 
	}
	return ajax;
}

七.检查账号是否存在

CheckNameController类

@Controller
public class CheckNameController {
	
	@RequestMapping("checkName")
	public void checkName(String username,HttpServletResponse response) throws IOException {
		response.setContentType("text/html;charset=utf-8");
		if ("admin".equals(username)) {
			response.getWriter().write("该用户已经被注册了");
		}else {
			response.getWriter().write("恭喜你,该用户可以注册");
		}
	}

}

index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="index.js"></script>
</head>
<body>
账号:<input type="text" name="usernmae" id="nameId"/>
<span id="sp"></span>
</body>
</html>

index.js

//页面加载完毕绑定时间
window.onload=function(){
	var inpEl = document.getElementById("nameId");
	//失去焦点时间
	inpEl.onblur=function(){
		//发送请求,检查用户是否存在
		var ajax = new XMLHttpRequest();
		//创建http请求对象
		ajax.open("get","/checkName.do?username="+inpEl.value,true);
		//设置http请求状态监听,并处理结果
		ajax.onreadystatechange=function(){
			//请求结果接收完毕,并且请求状态200时候再处理
			var sp = document.getElementById("sp");
			if(ajax.readyState == 4 && ajax.status==200){
				sp.innerHTML = ajax.responseText;
			}else{
				sp.innerHTML="亲网络范萌,请稍后再试~~";
			}
		}
		//发送请求
		ajax.send();
	}
}

八.用户登录操作

LoginController类

@Controller
public class LoginController {
	@RequestMapping("login")
	public void login(String username,String password,HttpServletResponse response) throws IOException {
		if ("admain".equals(username) && "12".equals(password)) {
			response.getWriter().write("登录成功");
		}else {
			response.getWriter().write("账号密码不正确");
		}
	}
}

index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="index.js"></script>
</head>
<body>
账号:<input type="text" name="username" id="nameId"/><br>
密码:<input type="text" name="password" id="passwordId"/><br>
<input type="button" value="登录" id="btn"/><br>
<span id="sp"></span><br>
</body>
</html>

inex.js

//页面加载完毕绑定时间
window.onload=function(){
	var inpEl = document.getElementById("nameId");
	var pwdId = document.getElementById("passwordId");
	var btn = document.getElementById("btn");
	//失去焦点时间
	btn.onclick=function(){
		//发送请求,检查用户是否存在
		var ajax = new XMLHttpRequest();
		//创建http请求对象
		ajax.open("post","/login.do",true);
		//设置http请求状态监听,并处理结果
		ajax.onreadystatechange=function(){
			//请求结果接收完毕,并且请求状态200时候再处理
			var sp = document.getElementById("sp");
			if(ajax.readyState == 4 && ajax.status==200){
				sp.innerHTML = ajax.responseText;
			}else{
				sp.innerHTML="亲网络范萌,请稍后再试~~";
			}
		}
		//在post请求提交之前,需要设置参数,编码格式
		//设置请求头
		ajax.setRequestHeader("Content-Type","application/x-www-form-urlencoded;charset=utf-8");
		//post请求参数拼接个get一样
		var params = "username="+inpEl.value+"&password="+pwdId.value;
		console.log(params);
		//post请求参数可以设置在send方法中
		//发送请求
		ajax.send(params);
	}
}

九.二级联动HTML格式

省份数据Province

/**
 * 省份对象
 */
public class Province {

	private Long id;//id
	private String name;//省份名字
	public Province() {
	}
	public Long getId() {
		return id;
	}

	public String getName() {
		return name;
	}

	public Province(Long id, String name) {
		this.id = id;
		this.name = name;
	}
	//获取所有的的省份信息
	public static List<Province> getAllProvince() {
		List<Province> provinces = new ArrayList<Province>();
		provinces.add(new Province(1L, "湖南"));
		provinces.add(new Province(2L, "广东"));
		provinces.add(new Province(3L, "湖北"));
		return provinces;
	}
	public String toString() {
		return "Province [id=" + id + ", name=" + name + "]";
	}

}

City数据

/**
 * 城市对象
 */
public class City {
	private Long id;
	private String name;

	public City() {
	}

	public City(Long id, String name) {
		this.id = id;
		this.name = name;
	}

	/**
	 * 根据省份id查询省份中的城市!
	 * @return
	 */
	public static List<City> getCityByProvinceId(Long pid) {
		
		List<City> citys = new ArrayList<City>();
		
		if (pid == 1) {
			citys = Arrays.asList(
					new City(11L,"长沙市"),
					new City(12L,"株洲市"),
					new City(13L,"湘潭市"),
					new City(14L,"衡阳市"),
					new City(15L,"邵阳市"),
					new City(16L,"岳阳市"),
					new City(17L,"常德市"),
					new City(18L,"张家界市")
			);
		} else if (pid == 2) {
			citys = Arrays.asList(
					new City(21L,"广州市"),
					new City(22L,"深圳市"),
					new City(23L,"佛山市"),
					new City(24L,"中山市"),
					new City(25L,"珠海市"),
					new City(26L,"汕头市"),
					new City(27L,"潮州市"),
					new City(28L,"东莞市")
			);
		} else if (pid == 3) {
			citys = Arrays.asList(
					new City(31L,"孝感市"),
					new City(32L,"黄冈市"),
					new City(33L,"咸宁市"),
					new City(34L,"恩施州"),
					new City(35L,"鄂州市"),
					new City(36L,"武汉市"),
					new City(37L,"荆门市"),
					new City(38L,"襄阳市")
			);
		}
		return citys;
	}
	
	public Long getId() {
		return id;
	}

	public String getName() {
		return name;
	}

	public String toString() {
		return "City [id=" + id + ", name=" + name + "]";
	}
}

拼接HTML格式数据

LinkageHTMLController

@Controller
@RequestMapping("myhtml")
public class LinkageHTMLController {
	/*格式
	 * <option>--请选择--</option>
		<option>广东</option>
		<option>上海</option>
	 */
	@RequestMapping("getProvinces")
	public void getProvinces(HttpServletResponse response) throws Exception {
		response.setContentType("text/html;charset=utf-8");
		List<Province> list = Province.getAllProvince();
		
		StringBuilder sb = new StringBuilder(100);
		for (Province vo : list) {
			sb.append("<option value='"+vo.getId()+"'>").append(vo.getName()).append("</option>");
		}
		response.getWriter().write(sb.toString());
	}
	/**
	 * 
	 * @param pid
	 * @param response
	 * @throws Exception
	 */
	@RequestMapping("getCities")
	public void getCities(Long pid,HttpServletResponse response) throws Exception {
		response.setContentType("text/html;charset=utf-8");
		List<City> list = City.getCityByProvinceId(pid);
		
		StringBuilder sb = new StringBuilder(100);
		for (City vo : list) {
			sb.append("<option value='"+vo.getId()+"'>").append(vo.getName()).append("</option>");
		}
		response.getWriter().write(sb.toString());
	}

}

index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<!-- json -->
<script type="text/javascript" src="linkage_json.js"></script>
<!-- xml -->
<!-- <script type="text/javascript" src="linkage_xml.js"></script> -->
<!-- html方式 -->
<!-- <script type="text/javascript" src="linkage_html.js"></script> -->
</head>
<body>
<select id="provinces">
	<option value="-1">--请选择--</option>
	</select>
<select id="cities">
	<option value="-1">--请选择--</option>
</select>

</body>
</html>

inkage_html.js

window.onload=function(){
	//省份
	var pEl = document.getElementById("provinces");
	var cEl = document.getElementById("cities");
	//页面加载完毕之后,通过ajax 获取所有的省份
	var ajax = new XMLHttpRequest();
	
	ajax.open("get","/myhtml/getProvinces.do",true);
	ajax.onreadystatechange=function(){
		if(ajax.readyState == 4&& ajax.status ==200){
			//已经是html格式,直接拼接即可
			pEl.innerHTML+=ajax.responseText;
		}
		
	}
	ajax.send();
	
	
	
	//城市:通过省份id获取
	pEl.onchange=function(){
		var pid = pEl.value;
		//清空原来的值
		cEl.innerHTML="<option value='-1'>--请选择--</option>";
		//当用户选中的省份是 请选择的时候没有必要发ajax请求
		if(pid==-1){
			return ;
		}
		//页面加载完毕之后,通过ajax 获取所有的省份
		var ajax = new XMLHttpRequest();
		ajax.open("get","/myhtml/getCities.do?pid="+pid,true);
		ajax.onreadystatechange=function(){
			if(ajax.readyState == 4&& ajax.status ==200){
				//已经是html格式,直接拼接即可
				cEl.innerHTML+=ajax.responseText;
			}
			
		}
		ajax.send();
	}
}

十.二级联动 XML格式

LinkageXMLController类

@Controller
@RequestMapping("xml")
public class LinkageXMLController {
	/*格式
	 * <datas>
	 * 	<data id='1'>湖南</data>
	 * 	<data id='2'>广东</data>
	 * 	<data id='3'>湖北</data>
	 * </datas>
	 */
	@RequestMapping("getProvinces")
	public void getProvinces(HttpServletResponse response) throws Exception {
		response.setContentType("text/xml;charset=utf-8");
		List<Province> list = Province.getAllProvince();
		
		//使用DOM操作
		//创建document
		org.w3c.dom.Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
		Element root = doc.createElement("datas");
		doc.appendChild(root);
		
		for (Province vo : list) {
			Element dataEl = doc.createElement("data");
			dataEl.setAttribute("id", vo.getId()+"");
			dataEl.setTextContent(vo.getName());
			root.appendChild(dataEl);
		}
		//同步更新(拼接好的xml格式文件输出到浏览器中)
		Transformer trans = TransformerFactory.newInstance().newTransformer();
		trans.transform(new DOMSource(doc), new StreamResult(response.getOutputStream()));
		
	}
	/**
	 * 
	 * @param pid
	 * @param response
	 * @throws Exception
	 */
	@RequestMapping("getCities")
	public void getCities(Long pid,HttpServletResponse response) throws Exception {
		response.setContentType("text/xml;charset=utf-8");
		List<City> list = City.getCityByProvinceId(pid);
		
		//使用DOM操作
		//创建document
		org.w3c.dom.Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
		Element root = doc.createElement("datas");
		doc.appendChild(root);
		
		for (City vo : list) {
			Element dataEl = doc.createElement("data");
			dataEl.setAttribute("id", vo.getId()+"");
			dataEl.setTextContent(vo.getName());
			root.appendChild(dataEl);
		}
		//同步更新(拼接好的xml格式文件输出到浏览器中)
		Transformer trans = TransformerFactory.newInstance().newTransformer();
		trans.transform(new DOMSource(doc), new StreamResult(response.getOutputStream()));
	}

}

linkage_json.js

window.onload=function(){
	//省份
	var pEl = document.getElementById("provinces");
	var cEl = document.getElementById("cities");
	//页面加载完毕之后,通过ajax 获取所有的省份
	var ajax = new XMLHttpRequest();
	
	ajax.open("get","/xml/getProvinces.do",true);
	ajax.onreadystatechange=function(){
		if(ajax.readyState == 4&& ajax.status ==200){
			//已经返回结果xml格式,所以拼接即可
			var doc = ajax.responseXML;
			console.log("xml");
			console.log(doc);
			var datas = doc.getElementsByTagName("data");
			//拼接option
			var opHTML="";
			for(var i=0;i<datas.length;i++){
				opHTML+="<option value='"+datas[i].id+"'>"
					+datas[i].innerHTML+"</option>";
			}
			pEl.innerHTML+=opHTML;
		}
		
	}
	ajax.send();
	
	
	
	//城市:通过省份id获取
	pEl.onchange=function(){
		var pid = pEl.value;
		//清空原来的值
		cEl.innerHTML="<option value='-1'>--请选择--</option>";
		//当用户选中的省份是 请选择的时候没有必要发ajax请求
		if(pid==-1){
			return ;
		}
		//页面加载完毕之后,通过ajax 获取所有的省份
		var ajax = new XMLHttpRequest();
		
		ajax.open("get","/xml/getCities.do?pid="+pid,true);
		ajax.onreadystatechange=function(){
			if(ajax.readyState == 4&& ajax.status ==200){
				//已经返回结果xml格式,所以拼接即可
				var doc = ajax.responseXML;
				console.log("xml");
				console.log(doc);
				var datas = doc.getElementsByTagName("data");
				//拼接option
				var opHTML="";
				for(var i=0;i<datas.length;i++){
					opHTML+="<option value='"+datas[i].id+"'>"
						+datas[i].innerHTML+"</option>";
				}
				cEl.innerHTML+=opHTML;
			}
			
		}
		ajax.send();
	}
}

十一.JSON数据格式

  1. JSON(JavaScript Object Notation)一种简单的数据格式,比xml更轻巧。易于人阅读和编写,同时也易于机器解析和生成(网络传输速度快)

  2. JSON是JavaScript原生格式,这意味着在JavaScript中处理JSON数据不需要任何特殊的API或工具包。

  3. 描述一个对象: {属性名1 : 属性值1 , 属性名2 : 属性值2}


JSON的规则很简单:

  1. 对象是一个无序的“‘名称/值’对”集合。一个对象以“{”(左括号)开始,“}”(右括号)结束。每个“名称”后跟一个“:”(冒号);“‘名称/值’对”之间使用“,”(逗号)分隔。
    1. 映射用冒号(“:”)表示。名称:值
    2. 并列的数据之间用逗号(“,”)分隔。名称1:值1,名称2:值2
    3. 映射的集合(对象)用大括号(“{}”)表示。{名称1:值1,名称2:值2}
    4. 并列数据的集合(数组)用方括号(“[]”)表示。
    [
       {名称1:值,名称2:值2},
       {名称1:值,名称2:值2}
    ]
    
    1. 元素值可具有的类型:string, number, object, array, true, false, null

index.html

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="index.js"></script>
</head>
<body>
</body>
</html>

index.js

//页面加载完毕绑定时间
window.onload=function(){
	var employee={
			id:1,
			name:"dusk",
			salary:1000,
			birthDate:new Date(),
			dept:{
				id:1,
				name:"开发部"
			}
	}
	console.log(employee);
	//获取属性
	console.log(employee.name);
	console.log(employee.dept.name);
	
	//json格式数组表示多个员工
	var es = [
		{id:1,name:"dusk",age:18},
		{id:1,name:"DUSK",age:19}
	];
	
	console.log(es);
	//使用json字符串转换json对象
	var json="{id:1,name:'dusk'}"
		console.log(json);
	//将js格式的字符串转换成js表达式
	console.log(eval("("+json+")"));
}

十二.操作JSON的库

  1. 因为手动拼接JSON数据格式效率比较低,而且不是特别的可靠,所以我们一般都会使用第三方的一些json操作的库来对JAVA对象转换为JSON字符串,也可以json字符串转换为java对象

  2. 在Java中,转换JSon的库有很多,两种常用的

  • jackson:在SpringMVC中内置的一个转换json的插件,速度也挺快,稳定性比较好
  • fastjson:阿里出品,号称是Java领域中转换Json最快的一个插件,中文文档比较齐全,用户量比较多

jackson:

1:添加jar

image

User类

@Data
@AllArgsConstructor
public class User {
	private Long id;
	private String username;
	private String password;
	private Date birthday = new Date();
	
	public Object toJson() {
		HashMap<String, Object> map = new HashMap<String,Object>();
		map.put("id",this.id);
		map.put("username",this.username);
		map.put("birthday", new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(birthday));
		return map;
	}

}
@Test
public void testFastSon() throws Exception {
	//1.单个Object转换成字符串
	String jsonS = JSON.toJSONString(new User(2L,"Dusk","333",null));
	System.out.println(jsonS);
	//2.成字符串 -->单个Object
	User u = JSON.parseObject(jsonS,User.class);
	System.out.println(u);
	//3.多个个Object转换成字符串
	List<User> list  = new ArrayList<>();
	list.add(new User(2L,"Dusk","333",null));
	list.add(new User(2L,"Dusk","333",null));
	list.add(new User(2L,"Dusk","333",null));
	list.add(new User(2L,"Dusk","333",null));
	String jsonL = JSON.toJSONString(list);
	System.out.println(jsonL);
	//4.json字符转换成多个User对象
	List<User> list2 = JSON.parseArray(jsonL, User.class);
	for (User user : list2) {
		System.out.println(user);
	}
}

fasjson

fastjson-1.2.41.jar

@Test
public void testJackSon() throws Exception {
	ObjectMapper mapper = new ObjectMapper();
	//1.单个Object转换成字符串
	String jsonS = mapper.writeValueAsString(new User(2L,"Dusk","333",null));
	System.err.println(jsonS);
	//2.成字符串 -->单个Object
	User u = mapper.readValue(jsonS, User.class);
	System.out.println(u);
	
	//3.多个个Object转换成字符串
	List<User> list  = new ArrayList<>();
	list.add(new User(2L,"Dusk","333",null));
	list.add(new User(2L,"Dusk","333",null));
	list.add(new User(2L,"Dusk","333",null));
	list.add(new User(2L,"Dusk","333",null));
	String jsonL = mapper.writeValueAsString(list);
	System.out.println(jsonL);
	//4.json字符转换成多个User对象
	JavaType javaType = mapper.getTypeFactory()
			//参数一:返回值类型,参数2:返回泛型
			.constructParametricType(ArrayList.class, User.class);
	List<User> list2 = mapper.readValue(jsonL, javaType);
	for (User user : list2) {
		System.err.println(user);
	}

十三.二级联动-JSON数据格式实现

LinkageJSONController类

//@Controller 表示该controller中所有方式返回都转换成json格式
@RestController
@RequestMapping("json")
public class LinkageJSONController {
	/*格式
		[
			{id:1,name:"湖南"},
			{id:2,name:"广东"},
			{id:3,name:"湖北"}
		]
	 */
	@RequestMapping("getProvinces")
	//@ResponseBody 返回数据的数据(对象)转换成json字符格式
	public List<Province> getProvinces(HttpServletResponse response) throws Exception {
		response.setContentType("text/json;charset=utf-8");
		 return Province.getAllProvince();
		
		/*StringBuilder sb = new StringBuilder(100);
		sb.append("[");
		for (Province vo : list) {
			sb.append("{id:"+vo.getId()+",name:'").append(vo.getName()+"'},");
		}
		//删除最后的逗号
		sb.deleteCharAt(sb.length()-1);
		sb.append("]");
		response.getWriter().write(sb.toString());
		*/
		//改进
		/*response.getWriter().write(JSON.toJSONString(list));*/
	}
	/**
	 * 
	 * @param pid
	 * @param response
	 * @throws Exception
	 */
	@RequestMapping("getCities")
	/*@ResponseBody*/
	public List<City> getCities(Long pid,HttpServletResponse response) throws Exception {
		response.setContentType("text/json;charset=utf-8");
		return City.getCityByProvinceId(pid);
		
		/*StringBuilder sb = new StringBuilder(100);
		sb.append("[");
		for (City vo : list) {
			sb.append("{id:"+vo.getId()+",name:'").append(vo.getName()+"'},");
		}
		//删除最后的逗号
		sb.deleteCharAt(sb.length()-1);
		sb.append("]");
		response.getWriter().write(sb.toString());*/
		//改进
		/*response.getWriter().write(JSON.toJSONString(list));*/
		
	}

}

linkage_json.js

window.onload=function(){
	//省份
	var pEl = document.getElementById("provinces");
	var cEl = document.getElementById("cities");
	//页面加载完毕之后,通过ajax 获取所有的省份
	var ajax = new XMLHttpRequest();
	
	ajax.open("get","/json/getProvinces.do",true);
	ajax.onreadystatechange=function(){
		if(ajax.readyState == 4&& ajax.status ==200){
			//已经返回结果json格式,所以拼接即可
			console.log("json");
			var ret = "("+ajax.responseText+")";
			console.log(ret);
			var jsonArr = eval("("+ajax.responseText+")");
			var opHTML="";
			for(var i=0;i< jsonArr.length;i++){
				opHTML += "<option value='"+jsonArr[i].id+"'>"+jsonArr[i].name+"</option>";
			}
			pEl.innerHTML+=opHTML;
		}
		
	}
	ajax.send();
	
	//城市:通过省份id获取
	pEl.onchange=function(){
		var pid = pEl.value;
		//清空原来的值
		cEl.innerHTML="<option value='-1'>--请选择--</option>";
		//当用户选中的省份是 请选择的时候没有必要发ajax请求
		if(pid==-1){
			return ;
		}
		//页面加载完毕之后,通过ajax 获取所有的省份
		var ajax = new XMLHttpRequest();
		
		ajax.open("get","/json/getCities.do?pid="+pid,true);
		ajax.onreadystatechange=function(){
			if(ajax.readyState == 4&& ajax.status ==200){
				//已经返回结果json格式,所以拼接即可
				var jsonArr = eval("("+ajax.responseText+")");
				console.log("json");
				console.log(jsonArr);
				var opHTML="";
				for(var i=0;i< jsonArr.length;i++){
					opHTML += "<option value='"+jsonArr[i].id+"'>"+jsonArr[i].name+"</option>";
				}
				cEl.innerHTML+=opHTML;
			}
			
		}
		ajax.send();
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值