AJAX
出现背景(问题):
目前浏览器向服务器发起请求的方式有 form 标签,超链接,还有脚本语言(jsjquery)中
的window.location.href 方式和表单提交函数。但是不管哪种提交方式,浏览器都会将接收
到的响应内容覆盖在请求网页中显示,但是怎么在保留请求网页内容的基础显示新的内容呢?
解决方法:
使用AJAX(改良用户体验,实现局部刷新)
与传统网页的区别:
传统的网页(不使用 AJAX)如果需要更新内容,必需重载整个网页面。
----------------------------------------------------------------------------------------------
AJAX简介
AJAX:Asynchronous JavaScript and XML(异步的 JavaScript 和 XML)
AJAX 是一种用于创建快速动态网页的技术。
通过在后台与服务器进行少量数据交换,AJAX 可以使网页实现异步更新。这意味着可以
在不重新加载整个网页的情况下,对网页的某部分进行更新。
----------------------------------------------------------------------------------------------
AJAX访问原理(及步骤)
![v2-8e35d4a9e343f9de467edf99e4cf714b_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=b2888fa9-1830-eb11-8da9-e4434bdf6706&url=https://pic4.zhimg.com/v2-8e35d4a9e343f9de467edf99e4cf714b_b.jpg)
----------------------------------------------------------------------------------------------
AJAX的应用
- 运用XHTML+CSS来表达资讯;
- 运用JavaScript操作DOM(Document Object Model)来执行动态效果;
- 运用XML和XSLT操作资料;
- 运用XMLHttpRequest或新的Fetch API与网页服务器进行异步资料交换;
- 注意:AJAX与Flash、Silverlight和Java Applet等RIA技术是有区分的。
************************************************************************************
创建AJAX对象(XMLHttpRequest 对象)
XMLHttpRequest 是 AJAX 的基础
所有现代浏览器(IE7+、Firefox、Chrome、Safari 以及 Opera)均内建 XMLHttpRequest 对象,但在老版本的浏览器中并不是,所以考虑充分的情况下,创建方法如下:
var ajax;
if (window.XMLHttpRequest)
{
// IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码
ajax=new XMLHttpRequest();
}
else if(window.ActiveXObject)
{
// IE6, IE5 浏览器执行代码
ajax=new ActiveXObject("Microsoft.XMLHTTP");
//ajax = new ActiveXObject("Msxml2.XMLHTTP");
}
AJAX - 向服务器发送请求请求
如需将请求发送到服务器,使用 XMLHttpRequest 对象的 open() 和 send() 方法:
![v2-4c1113b395fffa105e2c972f9f1d4cf4_b.jpg](http://img-01.proxy.5ce.com/view/image?&type=2&guid=b2888fa9-1830-eb11-8da9-e4434bdf6706&url=https://pic1.zhimg.com/v2-4c1113b395fffa105e2c972f9f1d4cf4_b.jpg)
-----------------------------------------------------------------------------------------------------
get请求与post请求:
与 POST 相比,GET 更简单也更快,并且在大部分情况下都能用。
然而,在以下情况中,请使用 POST 请求:
- 无法使用缓存文件(更新服务器上的文件或数据库)
- 向服务器发送大量数据(POST 没有数据量限制)
- 发送包含未知字符的用户输入时,POST 比 GET 更稳定也更可靠
异步 - True 或 False:
通过 AJAX,JavaScript 无需等待服务器的响应,而是:
- 在等待服务器响应时执行其他脚本
- 当响应就绪后对响应进行处理
AJAX - 服务器 响应:
![v2-4f8cc58522e2187a026d1e744884742d_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=b2888fa9-1830-eb11-8da9-e4434bdf6706&url=https://pic2.zhimg.com/v2-4f8cc58522e2187a026d1e744884742d_b.jpg)
如果来自服务器的响应并非 XML,可以使用responseText 属性返回字符串形式的响应
如果来自服务器的响应是 XML,而且需要作为 XML 对象进行解析,使用 responseXML 属性进行响应
实例:
get请求的同步、异步:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<script type="text/javascript">
//非ajax方法
function test1(){
window.location.href="test";
};
//ajax方法
function test2(){
//创建AJAX对象
var ajax;
if(window.XMLHttpRequest){
//火狐浏览器
ajax = new XMLHttpRequest();
}else if(window.ActiveXObject){
//IE浏览器
ajax = new ActiveXObject("Msxm12.XMLHTTP");
}
//声明监听事件
ajax.onreadystatechange = function(){
if(ajax.readyState==4){
if(ajax.status==200){
//处理响应
//获取响应内容
var data = ajax.responseText;
//获取div对象
var div = document.getElementById("showdiv");
div.innerHTML=data;
//alert(ajax.readyState);
}else if(ajax.status==404){
//获取div对象
var div = document.getElementById("showdiv");
div.innerHTML="访问资源不存在!";
}else if(ajax.status==500){
//获取div对象
var div = document.getElementById("showdiv");
div.innerHTML="内部服务器繁忙!";
}else{
//获取div对象
var div = document.getElementById("showdiv");
div.innerHTML="未知错误!";
}
}
};
//创建请求
//异步(默认)
//ajax.open("get","/ajax/test",true);
//同步
ajax.open("get","/ajax/test?userName=张三&pwd=123",false);
//发送请求
ajax.send(null);
var div = document.getElementById("showdiv");
alert(div.innerHTML);
};
</script>
</head>
<body>
<h3>ajax学习</h3>
<input type="button" value="测试非ajax" onclick="test1()" />
<input type="button" value="测试ajax" onclick="test2()" />
<hr />
<div id="showdiv" style="width: 200px;height: 200px;border: 1px solid red;"></div>
</body>
</html>
post请求的同步、异步:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<script type="text/javascript">
//非ajax方法
function test1(){
window.location.href="test";
};
//ajax方法
function test2(){
//创建AJAX对象
var ajax;
if(window.XMLHttpRequest){
//火狐浏览器
ajax = new XMLHttpRequest();
}else if(window.ActiveXObject){
//IE浏览器
ajax = new ActiveXObject("Msxml2.XMLHTTP");
}
//声明监听事件
ajax.onreadystatechange = function(){
if(ajax.readyState==4){
if(ajax.status==200){
//处理响应
//获取响应内容
var data = ajax.responseText;
//获取div对象
var div = document.getElementById("showdiv");
div.innerHTML=data;
//使用eval方法将字符串数据转换为js对象
eval("var obj="+data);//eval("var obj=
{userId:2,userName:'王五',pwd:'12345',age:45,sex:'男'}")
//获取div对象
var div=document.getElementById("showdiv");
div.innerHTML=obj.sex;
//alert(ajax.readyState);
}else if(ajax.status==404){
//获取div对象
var div = document.getElementById("showdiv");
div.innerHTML="访问资源不存在!";
}else if(ajax.status==500){
//获取div对象
var div = document.getElementById("showdiv");
div.innerHTML="内部服务器繁忙!";
}else{
//获取div对象
var div = document.getElementById("showdiv");
div.innerHTML="未知错误!";
}
}
};
//创建请求
//异步(默认)
//ajax.open("get","/ajax/test",true);
//同步
ajax.open("post","/ajax/test",false);
//设置请求参数为键值对方式
ajax.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
//发送请求
ajax.send("userName=张三&pwd=123");
var div = document.getElementById("showdiv");
alert(div.innerHTML);
};
</script>
</head>
<body>
<h3>ajax学习</h3>
<input type="button" value="测试非ajax" onclick="test1()" />
<input type="button" value="测试ajax" onclick="test2()" />
<hr />
<div id="showdiv" style="width: 200px;height: 200px;border: 1px solid red;"></div>
</body>
</html>
-----------------------------------------------------------------------------------------------------
AJAX - onreadystatechange 事件
当请求被发送到服务器时,我们需要执行一些基于响应的任务。
每当 readyState 改变时,就会触发 onreadystatechange 事件。
readyState 属性存有 XMLHttpRequest 的状态信息。
![v2-afb6c48633ff637e1046f45d1d190bc2_b.jpg](http://img-01.proxy.5ce.com/view/image?&type=2&guid=b2888fa9-1830-eb11-8da9-e4434bdf6706&url=https://pic3.zhimg.com/v2-afb6c48633ff637e1046f45d1d190bc2_b.jpg)
在 onreadystatechange 事件中,我们规定当服务器响应已做好被处理的准备时所执行的任务。
并且当 readyState 等于 4 且状态为 200 时,表示响应已就绪:
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("myDiv").innerHTML=xmlhttp.responseText;
}
}
///
AJAX实现用户名校验:
----数据库设计:
user表
![v2-50096a33583b8a5bd964a86223e7ab83_b.jpg](http://img-03.proxy.5ce.com/view/image?&type=2&guid=b2888fa9-1830-eb11-8da9-e4434bdf6706&url=https://pic4.zhimg.com/v2-50096a33583b8a5bd964a86223e7ab83_b.jpg)
----实体类(pojo)、Dao层、service层、servlet层、工具类(util)、properties设计
![v2-e4511aa1fb71c0863f43cb5719f1604b_b.jpg](http://img-03.proxy.5ce.com/view/image?&type=2&guid=b2888fa9-1830-eb11-8da9-e4434bdf6706&url=https://pic4.zhimg.com/v2-e4511aa1fb71c0863f43cb5719f1604b_b.jpg)
pojo实体类(User)
![v2-c323ec67230c396e3689835880c0dee7_b.jpg](http://img-03.proxy.5ce.com/view/image?&type=2&guid=b2888fa9-1830-eb11-8da9-e4434bdf6706&url=https://pic4.zhimg.com/v2-c323ec67230c396e3689835880c0dee7_b.jpg)
Dao层(封装方法):
![v2-aeaa8c87b35bb58b437b7dfd876f1428_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=b2888fa9-1830-eb11-8da9-e4434bdf6706&url=https://pic1.zhimg.com/v2-aeaa8c87b35bb58b437b7dfd876f1428_b.jpg)
![v2-55884abca4d2c8d3d90f774058419d46_b.jpg](http://img-03.proxy.5ce.com/view/image?&type=2&guid=b2888fa9-1830-eb11-8da9-e4434bdf6706&url=https://pic3.zhimg.com/v2-55884abca4d2c8d3d90f774058419d46_b.jpg)
package com.sxt.dao.impl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import com.sxt.dao.DataDao;
import com.sxt.util.DBUtil;
public class DataDaoImpl implements DataDao {
//查询用户名是否存在
@Override
public boolean checkUnameInfoDao(String uname) {
Connection conn = null;
PreparedStatement psmt= null;
ResultSet rs = null;
String sql = "select * from user where uname=?";
//声明变量
boolean flag = false;
try {
conn = DBUtil.getConnection();
psmt = conn.prepareStatement(sql);
psmt.setString(1,uname);
rs = psmt.executeQuery();
if(rs.next()){
//rs.getString("uname");
flag = true;
}
//System.out.println("rs集合:"+rs.getString("uname"));
} catch (SQLException e) {
e.printStackTrace();
}finally{
DBUtil.closeAll(rs, psmt, conn);
}
return flag;
}
}
service层:
![v2-c1a5a852858797d04e96646a51b18f63_b.jpg](http://img-03.proxy.5ce.com/view/image?&type=2&guid=b2888fa9-1830-eb11-8da9-e4434bdf6706&url=https://pic4.zhimg.com/v2-c1a5a852858797d04e96646a51b18f63_b.jpg)
![v2-9d583177687efa8d58df33a8995b3cbc_b.jpg](http://img-01.proxy.5ce.com/view/image?&type=2&guid=b2888fa9-1830-eb11-8da9-e4434bdf6706&url=https://pic1.zhimg.com/v2-9d583177687efa8d58df33a8995b3cbc_b.jpg)
servlet层(servlet方法):
package com.sxt.servlet;
import java.io.IOException;
import javax.security.auth.message.callback.PrivateKeyCallback.Request;
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 com.sxt.service.DataService;
import com.sxt.service.impl.DataServiceImpl;
public class DataServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)throws ServletException,IOException{
//设置请求编码集格式
req.setCharacterEncoding("utf-8");
//设置响应编码集格式
resp.setContentType("text/html;charset=utf-8");
//获取请求信息
String uname = req.getParameter("uname");
//System.out.println("DataServlet.service():"+uname);
//处理请求信息
//获取业务层对象
DataService ds = new DataServiceImpl();
boolean flag = ds.checkUnameInfoService(uname);
//响应处理结果
if(flag){
//用户已存在
resp.getWriter().write("true");
}else{
//用户不存在
resp.getWriter().write("false");
}
}
}
Jsp文件:
<%@ page language="java" import="java.util.*" contentType="text/html" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<script type="text/javascript">
//声明用户名校验函数
function checkUname(){
var uname = document.getElementById("uname").value;
//创建ajax引擎对象
var ajax;
if(window.XMLHttpRequest){
ajax = new XMLHttpRequest;
}else if(window.ActiveXObject){
ajax = new ActiveXObject;
}
//声明监听函数
ajax.onreadystatechange = function(){
//判断ajax状态码
if(ajax.readyState==4){
//判断状态
if(ajax.status==200){
//获取响应数据(普通字符串或者json格式的字符串)
var data = ajax.responseText;
//处理请求数据
if(eval(data)){
//获取span对象
var span = document.getElementById("unameSpan");
//设置span随想颜色
span.style.color="red";
//将数据填充到span中
span.innerHTML="用户名已被占用!";
}else{
//获取span对象
var span = document.getElementById("unameSpan");
//设置span随想颜色
span.style.color="green";
//将数据填充到span中
span.innerHTML="用户名OK";
}
}else{
//获取span对象
var span = document.getElementById("unameSpan");
//设置span随想颜色
span.style.color="red";
//将数据填充到span中
span.innerHTML="未知错误!";
}
}
};
//创建并发送请求
//创建请求
ajax.open("get","data?uname="+uname);
//发送请求
ajax.send(null);
};
</script>
</head>
<body>
用户名:<input name="uname" id="uname" value="" type="text" onblur="checkUname()" /><span id="unameSpan"></span>
</body>
</html>
工具类(DButil):
package com.sxt.util;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
public class DBUtil {
// 声明全局变量记录jdbc参数
private static String driver;
private static String url;
private static String username;
private static String password;
// 使用静态代码块,在类加载时即完成对属性文件的读取
static {
// 动态获取属性配置文件的流对象
InputStream in = DBUtil.class.getResourceAsStream("/db.properties");
// 创建Properties对象
Properties p = new Properties();
// 加载
try {
p.load(in);// 会将属性配置文件的所有数据存储到Properties对象中
// 将读取的jdbc参数赋值给全局变量
driver = p.getProperty("driver");
url = p.getProperty("url");
username = p.getProperty("username");
password = p.getProperty("password");
// 加载驱动
Class.forName(driver);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 创建连接对象并返回
public static Connection getConnection() {
Connection conn = null;
try {
conn = DriverManager.getConnection(url, username, password);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return conn;
}
// 关闭资源
public static void closeAll(ResultSet rs, Statement stmt, Connection conn) {
try {
if (rs != null) {
rs.close();
}
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
stmt.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 封装增加删除修改的通用工具方法
/**
* @param sql
* SQL语句
* @param objs
* SQL语句占位符实参,如果没有参数则传入null
* @return 返回增删改的结果,类型为int
*/
public static int executeDML(String sql, Object... objs) {
// 声明jdbc变量
Connection conn = null;
PreparedStatement ps = null;
int i = -1;
try {
// 获取连接对象
conn = DBUtil.getConnection();
// 开启事务管理
conn.setAutoCommit(false);
// 创建SQL命令对象
ps = conn.prepareStatement(sql);
// 给占位符赋值
if (objs != null) {
for (int j = 0; j < objs.length; j++) {
ps.setObject(j + 1, objs[j]);
}
}
// 执行SQL
i = ps.executeUpdate();
conn.commit();
} catch (Exception e) {
try {
conn.rollback();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
e.printStackTrace();
} finally {
DBUtil.closeAll(null, ps, conn);
}
return i;
}
}
----web.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<servlet>
<servlet-name>DataServlet</servlet-name>
<servlet-class>com.sxt.servlet.DataServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DataServlet</servlet-name>
<url-pattern>/data</url-pattern>
</servlet-mapping>
</web-app>
----db.properties配置
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/project?useUnicode=true&characterEncoding=UTF-8
username=root
password=0100
效果:
![v2-d5c4724fa362a347ee67dbb935a14e76_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=b2888fa9-1830-eb11-8da9-e4434bdf6706&url=https://pic3.zhimg.com/v2-d5c4724fa362a347ee67dbb935a14e76_b.jpg)
![v2-161c2c445efb2eb0662f3c2bdee00e88_b.jpg](http://img-03.proxy.5ce.com/view/image?&type=2&guid=b2888fa9-1830-eb11-8da9-e4434bdf6706&url=https://pic1.zhimg.com/v2-161c2c445efb2eb0662f3c2bdee00e88_b.jpg)
JSON
JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。 易于人阅读和编写。同时也易于机器解析和生成。
它基于JavaScript Programming Language,Standard ECMA-262 3rd Edition - December 1999的一个子集。
JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。 这些特性使JSON成为理想的数据交换语言。
JSON构建格式:
“名称/值”对的集合(A collection of name/value pairs)。不同的语言中,它被理解为对象(object),纪录(record),结构(struct),字典(dictionary),哈希表(hash table),有键列表(keyed list),或者关联数组 (associative array)。
JSON具有以下这些形式:
1. 对象是一个无序的“‘名称/值’对”集合。一个对象以{
左括号开始,以}
右括号结束。每个“名称”后跟一个:
冒号;“‘名称/值’ 对”之间使用,
逗号分隔
![v2-07890c157a036fcdae49ab4a10ef7b0b_b.jpg](http://img-03.proxy.5ce.com/view/image?&type=2&guid=b2888fa9-1830-eb11-8da9-e4434bdf6706&url=https://pic4.zhimg.com/v2-07890c157a036fcdae49ab4a10ef7b0b_b.jpg)
2. 数组是值(value)的有序集合。一个数组以[
左中括号开始,]
右中括号结束。值之间使用,
逗号分隔
![v2-06446ed6b35dfb8eaeb7e805e79db8ab_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=b2888fa9-1830-eb11-8da9-e4434bdf6706&url=https://pic4.zhimg.com/v2-06446ed6b35dfb8eaeb7e805e79db8ab_b.jpg)
3. 值(value)可以是双引号括起来的字符串(string)、数值(number)、true
、false
、null
、对象(object)或者数组(array)。这些结构可以嵌套
![v2-a64524a0cbc5bbaf414aa7405b309303_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=b2888fa9-1830-eb11-8da9-e4434bdf6706&url=https://pic4.zhimg.com/v2-a64524a0cbc5bbaf414aa7405b309303_b.jpg)
实例:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<script type="text/javascript">
function test1(){
var student = {'id':12,'name':'张三','age':23,'sex':'男'};
alert(student.id+"--"+student.name+"--"+student.age+"--"+student.sex);
};
function test2(){
var week = ['星期一','星期二','星期三','星期四','星期五','星期六','星期日'];
for(var i=0;i<week.length;i++){
alert(week[i]);
}
};
function test3() {
var stu =[{'id':1,'name':'张三','age':23,'sex':'男'},{'id':2,'name':'李四','age':24,'sex':'男'}];
for(var i=0;i<stu.length;i++){
var student = stu[i];
alert(student.id+"--"+student.name+"--"+student.age+"--"+student.sex);
}
};
</script>
</head>
<body>
<input type="button" value="测试json格式的对象" onclick="test1()" />
<input type="button" value="测试json格式的数组" onclick="test2()" />
<input type="button" value="测试json格式的数组对象" onclick="test3()" />
</body>
</html
-------------------------------------------------------------------------------------------------------------------
JQuery中的AJAX
jquery是js的一个轻量型框架,已经将js创建的操作进行了封装,而ajax也是js的一部分,所以jQuery也已经将ajax进行了封装。
JQuery中封装的方法:
![v2-aa6d8a3352108069ec2b1679965340ad_b.jpg](http://img-03.proxy.5ce.com/view/image?&type=2&guid=b2888fa9-1830-eb11-8da9-e4434bdf6706&url=https://pic2.zhimg.com/v2-aa6d8a3352108069ec2b1679965340ad_b.jpg)
常用的三种:
A. $.get(url,[data],[function])
$.get() 方法通过 HTTP GET 请求从服务器上请求数据
url:请求地址
data:请求参数,参数格式为json对象
function:发送成功时回调函数,注意函数要声明一个形参,用来接收响应数据。
$.get() 方法实现用户名校验(Jquery1-get.jsp):
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<script type="text/javascript" src="js/jquery-1.9.1.js"></script>
<script type="text/javascript">
$(function(){
$("#userName").blur(function(){
var userName = $(this).val();
//使用JQuery中的$.get(url,[data],[callback])向服务器端发送get的ajax请求
$.get("check",{"userName":userName},function(data){
if(data=='true'){
document.getElementById("userNameSpan").innerHTML="<font color=red>用户名已存在!</font>";
}else if(data=='false'){
document.getElementById("userNameSpan").innerHTML="<font color=green>用户名可用</font>";
}
});
});
});
</script>
</head>
<body>
用户名:<input type="text" name="userName" id="userName" /><span id="userNameSpan"></span>
</body>
</html>
![v2-abab238335a8c9a5f981dbc380d86cba_b.jpg](http://img-01.proxy.5ce.com/view/image?&type=2&guid=b2888fa9-1830-eb11-8da9-e4434bdf6706&url=https://pic3.zhimg.com/v2-abab238335a8c9a5f981dbc380d86cba_b.jpg)
![v2-f46f8f5a835567ba9130c5f16241b30c_b.jpg](http://img-03.proxy.5ce.com/view/image?&type=2&guid=b2888fa9-1830-eb11-8da9-e4434bdf6706&url=https://pic1.zhimg.com/v2-f46f8f5a835567ba9130c5f16241b30c_b.jpg)
B. $.post(url,[data],[function])
$.post() 方法通过 HTTP POST 请求向服务器提交数据
url:请求地址
data:请求参数,参数格式为json对象
function:发送成功时回调函数,注意函数要声明一个形参,用来接收响应数据。
$.post() 方法实现用户名校验(Jquery2-post.jsp):
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<script type="text/javascript" src="js/jquery-1.9.1.js"></script>
<script type="text/javascript">
$(function(){
$("#userName").blur(function(){
var userName = $(this).val();
//使用JQuery中的$.post(url,[data],[callback])向服务器端发送post的ajax请求
$.post("check",{'userName':userName},function(data){
if(data=='true'){
document.getElementById("userNameSpan").innerHTML="<font color=red>用户名已存在!</font>";
}else if(data=='false'){
document.getElementById("userNameSpan").innerHTML="<font color=green>用户名可用</font>";
}
});
});
});
</script>
</head>
<body>
用户名:<input type="text" name="userName" id="userName" /><span id="userNameSpan"></span>
</body>
</html>
![v2-f787da35e5edbc822141f71d4caec9b5_b.jpg](http://img-03.proxy.5ce.com/view/image?&type=2&guid=b2888fa9-1830-eb11-8da9-e4434bdf6706&url=https://pic2.zhimg.com/v2-f787da35e5edbc822141f71d4caec9b5_b.jpg)
![v2-89b7ee7d8a8ddb1911559d9fa2f9a163_b.jpg](http://img-01.proxy.5ce.com/view/image?&type=2&guid=b2888fa9-1830-eb11-8da9-e4434bdf6706&url=https://pic4.zhimg.com/v2-89b7ee7d8a8ddb1911559d9fa2f9a163_b.jpg)
*******************************************************************************************************
注意:
$.post与$.get其实就是对$.ajax进行了更进一步的封装,减少了参数,简化了操作,但是运用的范围更小了
简化了数据提交方式,只能采用POST方式提交。
只能是异步访问服务器,不能同步访问,不能进行错误处理
它的主要几个参数,像method,async等进行了默认设置,我们不可以改变的
C. $.ajax({json格式参数}):参数说明参照api
$.ajax({
method //数据的提交方式:get和post
url //数据的提交路径
async //是否支持异步刷新,默认是true
data //需要提交的数据
dataType //服务器返回数据的类型,例如xml,String,Json等
success //请求成功后的回调函数
error //请求失败后的回调函数
});
通过使用这个函数可以完成异步通讯的所有功能
$.ajax中其余参数的设置:
![v2-c04915c41f9535be13144e65764bc79d_b.jpg](http://img-01.proxy.5ce.com/view/image?&type=2&guid=b2888fa9-1830-eb11-8da9-e4434bdf6706&url=https://pic2.zhimg.com/v2-c04915c41f9535be13144e65764bc79d_b.jpg)
![v2-1dbe26808cb483fcadda2e64b150dba9_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=b2888fa9-1830-eb11-8da9-e4434bdf6706&url=https://pic2.zhimg.com/v2-1dbe26808cb483fcadda2e64b150dba9_b.jpg)
![v2-3a8f941e53a0418a765f0096ed7f24a2_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=b2888fa9-1830-eb11-8da9-e4434bdf6706&url=https://pic3.zhimg.com/v2-3a8f941e53a0418a765f0096ed7f24a2_b.jpg)
![v2-1666373038d8d2745f59aa05298d3c67_b.jpg](http://img-03.proxy.5ce.com/view/image?&type=2&guid=b2888fa9-1830-eb11-8da9-e4434bdf6706&url=https://pic4.zhimg.com/v2-1666373038d8d2745f59aa05298d3c67_b.jpg)
![v2-f4308f93b7b659a95a063a5874b79c51_b.jpg](http://img-01.proxy.5ce.com/view/image?&type=2&guid=b2888fa9-1830-eb11-8da9-e4434bdf6706&url=https://pic2.zhimg.com/v2-f4308f93b7b659a95a063a5874b79c51_b.jpg)
![v2-68c0e30e4301fa731bce8b686ba8fe5f_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=b2888fa9-1830-eb11-8da9-e4434bdf6706&url=https://pic4.zhimg.com/v2-68c0e30e4301fa731bce8b686ba8fe5f_b.jpg)
![v2-f19e62157c82b0d9e5351bb6a453e238_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=b2888fa9-1830-eb11-8da9-e4434bdf6706&url=https://pic1.zhimg.com/v2-f19e62157c82b0d9e5351bb6a453e238_b.jpg)
注意:
![v2-da2596d9186ad1341c635b23c814a8b1_b.jpg](http://img-03.proxy.5ce.com/view/image?&type=2&guid=b2888fa9-1830-eb11-8da9-e4434bdf6706&url=https://pic2.zhimg.com/v2-da2596d9186ad1341c635b23c814a8b1_b.jpg)
$.ajax()方法实现用户名校验(Jquery3-ajax.jsp):
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<script type="text/javascript" src="js/jquery-1.9.1.js"></script>
<script>
$(function(){
$("#userName").blur(function(){
var userName = $(this).val();
$.ajax({
type:'get',
url:'check',
data:{'userName':userName},
//data:'userName='+userName
success:function(data){
if(data=='true'){
document.getElementById("userNameSpan").innerHTML="<font color=red>用户名已存在!</font>";
}else if(data=='false'){
document.getElementById("userNameSpan").innerHTML="<font color=green>用户名可用</font>";
}
}
});
});
});
</script>
</head>
<body>
用户名:<input type="text" name="userName" id="userName" /><span id="userNameSpan"></span>
</body>
</html>
![v2-9ecbeef93bf31f9e435894d477e76c4f_b.jpg](http://img-03.proxy.5ce.com/view/image?&type=2&guid=b2888fa9-1830-eb11-8da9-e4434bdf6706&url=https://pic4.zhimg.com/v2-9ecbeef93bf31f9e435894d477e76c4f_b.jpg)
![v2-6fa457584e9c4e5898be3226caf05f73_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=b2888fa9-1830-eb11-8da9-e4434bdf6706&url=https://pic4.zhimg.com/v2-6fa457584e9c4e5898be3226caf05f73_b.jpg)
校验的内容(未连接数据库):
package com.sxt.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/check")
public class CheckServlet extends HttpServlet{
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
//获取客户端提交的用户名
String userName = request.getParameter("userName");
try {
Thread.sleep(450);//休眠3秒
} catch (InterruptedException e) {
e.printStackTrace();
}
//根据用户名查询数据库是否存在
if("admin".equals(userName)){
//用户已存在
out.print("true");
}else{
//用户名可用
out.print("false");
}
}
}
![v2-0134cbaf21154c5a720eb5648a8de0de_b.jpg](http://img-03.proxy.5ce.com/view/image?&type=2&guid=b2888fa9-1830-eb11-8da9-e4434bdf6706&url=https://pic3.zhimg.com/v2-0134cbaf21154c5a720eb5648a8de0de_b.jpg)
普通方法实现用户名校验(index.jsp):
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>校验用户名是否存在</title>
<script type="text/javascript">
var xmlHttpRequest;
//针对不同的浏览器,创建XMLHttpRequest对象
function createXMLHttpRequest(){
//根据不同的浏览器创建XMLHttpRequest对象
if(window.ActiveXObject){//IE浏览器(IE5 IE6)
xmlHttpRequest = new ActiveXObject("Microsoft.XMLHTTP");
}else{
xmlHttpRequest = new XMLHttpRequest();
}
}
//校验用户名是否存在
function checkUserName(){
//1.获取输入的用户名
var userName = document.getElementById("userName").value;
//2.创建XMLHttpRequest对象
createXMLHttpRequest();
//3.打开连接:xmlHttpRequest.open(method,url,true|false)
xmlHttpRequest.open('GET','check?userName='+userName,true);
//4.发送请求:send([data]);
xmlHttpRequest.send(null);
//5.注册回调函数
xmlHttpRequest.onreadystatechange=callBack;
}
//回调函数:处理服务器端返回的结果
function callBack(){
if (xmlHttpRequest.readyState==4 && xmlHttpRequest.status==200){
var content = xmlHttpRequest.responseText;
if(content=='true'){
document.getElementById("userNameSpan").innerHTML="<font color=red>用户名已存在!</font>";
}else{
document.getElementById("userNameSpan").innerHTML="<font color=green>用户名可用</font>";
}
}
}
</script>
</head>
<body>
用户名:<input type="text" name="userName" id="userName" onblur="checkUserName()" /><span id="userNameSpan" ></span>
</body>
</html>
![v2-fc9de450878e866b365885169ec25a65_b.jpg](http://img-03.proxy.5ce.com/view/image?&type=2&guid=b2888fa9-1830-eb11-8da9-e4434bdf6706&url=https://pic2.zhimg.com/v2-fc9de450878e866b365885169ec25a65_b.jpg)
![v2-20ae48b63a7c6ff70096a1fba80b168a_b.jpg](http://img-01.proxy.5ce.com/view/image?&type=2&guid=b2888fa9-1830-eb11-8da9-e4434bdf6706&url=https://pic3.zhimg.com/v2-20ae48b63a7c6ff70096a1fba80b168a_b.jpg)
-------------------------------------------------------------------------------------------------------------------------
实例1(省、市、区县的三级联动):
功能需求:
页面中有三个下拉框选项,分别为省下拉框,市下拉框,区/县下拉框
选择省,则市下拉框中出现对应的该省下的市信息,选择市,则区/县下拉框中
出现对应的该市下面的区/县信息
技术分析:
ajax技术+jsp+servlet+jdbc
需求分析(思路):
1、创建页面:页面中有三个下拉框,分别为省、市、区/县
2、页面加载成功发起ajax请求,请求省的信息,并将响应结果
填充到省下拉框中
3、选择省触发一个新的js函数 的执行,该函数中发起新的ajax请求
请求该省下的市信息,并将响应数据填充到市下拉框
4、选择市信息触发一个新的js函数的执行,该函数中发起新的ajax请求
请求该市下的区/县信息,并将数据填充到区/县下拉框中
数据库设计:
创建表(area):存储了省、市、区/县信息
设计表实现一:
地区id:areaid
地区名:areaname
不足:只存储了数据,但是数据之间的层级关系(混乱)没有存储
设计表实现二:
地区id:areaid
地区名:areaname
地区上级id:parentid
sql语句设计:
查询所有的省信息:
select * from area where parentid=0;
查询选择的省的市信息(假如:选择的山东省的areaid为110000,)
select * from area where parentid=110000;
查询选择的市的区/县信息(假如:选择的山东省的济南市areaid为110001)
select * from area where parentid =110001;
提取共性,代码整合
select * from area where parentid=?;
数据库实现:将资料中提供的area.sql文件导入到数据库中即可
代码缺陷:
发现请求省,市,县的代码中基本上是一致的。代码的冗余量有点大
解决:
考虑使用封装
实现思想:形同的保留,不同的传参
![v2-9d1c73df43cc30795956b335b46b5c7e_b.jpg](http://img-01.proxy.5ce.com/view/image?&type=2&guid=b2888fa9-1830-eb11-8da9-e4434bdf6706&url=https://pic3.zhimg.com/v2-9d1c73df43cc30795956b335b46b5c7e_b.jpg)
实现方式一(三种JQuery方式进行操作,但是未实现三级联动):
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<script type="text/javascript" src="js/jquery-1.9.1.js"></script>
<script>
//省下拉框
function loadingProvince() {
//使用jquery中的$.get(url,[data],[callback]);
$.get("select?parentid=0",function(data){
//使用eval()函数将json字符串转换为json对象
var json = eval(data);
for(var i=0;i<json.length;i++){
var province = json[i];
//alert(province.areaname);
$("#province").append("<option value='"+province.areaid+"'>"+province.areaname+"</option>");
}
});
}
//市下拉框
function loadingCity(value) {
//获取当前选中省份的areaid
var areaid = value;
//使用jquery中的$.post(url,[data],[callback]);
$.post("select?parentid="+areaid,function(data){
//使用eval()函数将json字符串转换为json对象
var json = eval(data);
//清空选项(之前运行保留的信息)
$("#city").empty();
for(var i=0;i<json.length;i++){
var city = json[i];
$("#city").append("<option value='"+city.areaid+"'>"+city.areaname+"</option>");
}
});
}
//区县下拉框
function loadingTown(value) {
//获取选中市的areaid
var areaid = value;
$.ajax({
type:"get",
url:"select?parentid="+areaid,
success:function(data){
var json = eval(data);
//清空选项(之前运行保留的信息)
$("#town").empty();
for(var i=0;i<json.length;i++){
var town = json[i];
$("#town").append("<option value='"+town.areaid+"'>"+town.areaname+"</option>");
}
}
});
}
</script>
</head>
<body onload="loadingProvince()">
省<select name="province" id="province" onchange="loadingCity(this.value)" ></select>
市<select name="city" id="city" onchange="loadingTown(this.value)" ></select>
区县<select name="town" id="town" ></select>
</body>
</html>
![v2-16d8ad0aca1bee4b9298b58498846bfc_b.png](http://img-03.proxy.5ce.com/view/image?&type=2&guid=b2888fa9-1830-eb11-8da9-e4434bdf6706&url=https://pic1.zhimg.com/v2-16d8ad0aca1bee4b9298b58498846bfc_b.png)
实现方式二:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<script type="text/javascript" src="js/jquery-1.9.1.js"></script>
<script>
$(function(){
//省下拉框
$.get("select",{parentid:0},function(data){
//alert(data);
var data = eval(data);
//清空原有内容
$("#province").empty();
for(var i=0;i<data.length;i++){
$("#province").append("<option value='"+data[i].areaid+"'>"+data[i].areaname+"</option>");
}
$("#province").trigger("change");
});
//市下拉框
$("#province").change(function(){
var areaid = $("#province").val();
$.get("select",{parentid:+areaid},function(data){
eval("var data ="+data);
//清空原有内容
$("#city").empty();
for(var i=0;i<data.length;i++){
$("#city").append("<option value='"+data[i].areaid+"'>"+data[i].areaname+"</option>");
}
$("#city").trigger("change");
});
});
//区县下拉框
$("#city").change(function(){
var areaid = $("#city").val();
$.get("select",{parentid:+areaid},function(data){
eval("var data ="+data);
//清空原有内容
$("#town").empty();
for(var i=0;i<data.length;i++){
$("#town").append("<option value='"+data[i].areaid+"'>"+data[i].areaname+"</option>");
}
});
});
});
</script>
</head>
<body>
省<select name="province" id="province" ></select>
市<select name="city" id="city" ></select>
区县<select name="town" id="town" ></select>
</body>
</html>
![v2-c922b05964f59dd5b8a9c307fbfa4360_b.jpg](http://img-01.proxy.5ce.com/view/image?&type=2&guid=b2888fa9-1830-eb11-8da9-e4434bdf6706&url=https://pic1.zhimg.com/v2-c922b05964f59dd5b8a9c307fbfa4360_b.jpg)
效果:
![v2-84dfb7235979126cc403fb56342f2956_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=b2888fa9-1830-eb11-8da9-e4434bdf6706&url=https://pic3.zhimg.com/v2-84dfb7235979126cc403fb56342f2956_b.jpg)
![v2-2966dbcb2d0cf03d5c231e03925ff0f1_b.png](http://img-02.proxy.5ce.com/view/image?&type=2&guid=b2888fa9-1830-eb11-8da9-e4434bdf6706&url=https://pic2.zhimg.com/v2-2966dbcb2d0cf03d5c231e03925ff0f1_b.png)
实现方式三(提取共有的代码,将形同的保留,不同的传参):
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<script type="text/javascript" src="js/jquery-1.9.1.js"></script>
<script>
$(function(){
//省下拉框
getData(0,"province");
//市下拉框
$("#province").change(function(){
var areaid = $("#province").val();
getData(areaid,"city");
});
//区县下拉框
$("#city").change(function(){
var areaid = $("#city").val();
getData(areaid,"town");
});
});
//提取公共方法
function getData(areaid,sid){
$.get("select",{parentid:+areaid},function(data){
eval("var data ="+data);
//清空原有内容
$("#"+sid).empty();
for(var i=0;i<data.length;i++){
$("#"+sid).append("<option value='"+data[i].areaid+"'>"+data[i].areaname+"</option>");
}
$("#"+sid).trigger("change");
});
}
</script>
</head>
<body>
省<select name="province" id="province" ></select>
市<select name="city" id="city" ></select>
区县<select name="town" id="town" ></select>
</body>
</html>
实例2(搜索框提示功能)
功能需求:
用户在搜索框中输入关键字,然后搜索框下出现下拉选项,提示关键字的提示语。
用户可以使用鼠标进行提示语的选择,也可以使用键盘的上下键来进行选择。
技术分析:
ajax技术+servlet+jsp+jdbc
功能分析(思路):
1、创建搜索界面(搜索框和提示语div和搜索按钮)
2、给搜索框添加onkeyup事件,键盘弹起时发送ajax请求
请求当前用户输入的信息对应的提示语数据
3、将提示语数据填充到搜索框下的div中
问题:
现在用户在搜索框上单击键盘的任意一个键都会发起ajax请求,请求提示语数据。
解决:
判断用户单击的键盘的按键符合要求再发请求。
解决:
获取用户按了键盘的哪个键。使用event对象进行按键的键盘码值获取
4、实现使用鼠标选择提示语
5、实现使用键盘的上和下键选择提示语
6、实现鼠标和键盘的联动操作
7、将显示提示语的div进行隐藏,当有提示语的时候显示隐藏的div
完善:
问题1:只要用户在搜索框中出现键盘点击动作,都会触发键盘事件的执行。
而只要数据符合要求,都会发送ajax请求,请求提示语信息。点击一次都发一次。
但是其实只需要最后一次进行请求发生即可。
解决1:
使用延迟发送请求。
使用1:
window.setTimeout
问题2:
event对象在火狐浏览器中使用window.event获取不到。
解决2:
在获取浏览器中使用传参的方式给event进行赋值。
使用:参照源码即可
数据库设计:
创建表:(data) 存储了常用的关键字数据
关键字编号:id(主键、自增)
关键字数据:title(not null)
说明:remark
添加测试数据:要求前期测试数据为英文单词
SQL语句设计:查询以用户当前搜索框数据开头的关键字
select * from t_data where title like 'a%'
select * from t_data where title like concat(?,'%');
注意:测试数据不要太多。
数据库实现:在数据库中创建表即可,并添加测试数据。
![v2-f629439179a2c88478400b5c42ecc665_b.jpg](http://img-02.proxy.5ce.com/view/image?&type=2&guid=b2888fa9-1830-eb11-8da9-e4434bdf6706&url=https://pic2.zhimg.com/v2-f629439179a2c88478400b5c42ecc665_b.jpg)
jsp书写:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<script type="text/javascript" src="js/jquery-1.9.1.js"></script>
<script type="text/javascript">
//创建计数器
var count = -1;
//声明变量记录定时执行的编码
var id;
//页面加载成功完成页面资源的初始化
$(function(){
$("#search").keyup(function(event){
//获取event事件(火狐浏览器某些版本使用event直接获取)
var even = window.event || event;
var code = even.keyCode;
//声明正则表达式判断空格
var reg=/^s+$/g;
//26个字母 回退键 空格
if(code>=65&code<=90||code==8||code==32){
//获取当前搜索框中输入的信息
var message = $("#search").val();
if(message==""||reg.test(message)){
return;
}
//清空将要发送的请求数据
window.clearTimeout(id);
//延迟发送请求
id = window.setTimeout(function(){
//$.post("search",{sdata:message},function(data){
$.get("search",{sdata:message},function(data){
//var sd = eval(data);
eval("var sd ="+data);
//alert(sd)
var dataDiv = $("#dataDiv");
//显示隐藏的div
if(sd.length>0){
dataDiv.css("display","");
}
dataDiv.empty();
for(var i=0;i<sd.length;i++){
//dataDiv.append("<div>'"+sd[i].title+"'</div>");
dataDiv.append("<div>"+sd[i].title+"</div>");
}
//给提示语添加鼠标选择效果
$("#dataDiv div").mouseover(function(){
//清空所有提示语的div的背景颜色
$("#dataDiv div").css("background-color","");
//将当前选择的div北京颜色变成灰色
$(this).css("background-color","gray");
//添加鼠标、上下键的联动效果----将当前鼠标选择的div的角标赋值给计数器
count=$(this).index();
});
//给提示语div添加单击事件,用来选择提示语
$("#dataDiv div").click(function(){
//将当前选择的div中的提示语数据改变到搜索框中
$("#search").val($(this).html());
//隐藏当前填充所有提示语的div
$("#dataDiv").css("display","none");
});
});
},1000);
}
//添加向下按键的事件----判断用户点击的是否是键盘的下键
if(code==40){
//判断是否有提示语
if($("#dataDiv div").length>0){
//判断向下是否超过界限
count=count<$("#dataDiv div").length-1?++count:0;
//清空所有提示语的div的背景颜色
$("#dataDiv div").css("background-color","");
//让提示语div中第一个提示语的背景色变成灰色
$("#dataDiv div:eq("+count+")").css("background-color","gray");
//将选择的提示语改变到搜索框中
$("#search").val($("#dataDiv div:eq("+count+")").html());
}
}
//添加向上按键的事件----判断用户点击的是否是键盘的上键
if(code==38){
//判断是否有提示语
if($("#dataDiv div").length>0){
//判断向上是否超过界限
count=count>0?--count:$("#dataDiv div").length-1;
//清空所有提示语的div的背景颜色
$("#dataDiv div").css("background-color","");
//让提示语div中第一个提示语的背景色变成灰色
$("#dataDiv div:eq("+count+")").css("background-color","gray");
//将选择的提示语改变到搜索框中
$("#search").val($("#dataDiv div:eq("+count+")").html());
}
}
});
});
</script>
</head>
<body>
<!-- 创建div容器将提示语div和搜索框div显示到一起 -->
<div id="container" style="width: 550px;margin: auto;">
<!-- 创建div进行搜索框的布局 -->
<div id="sdiv" style="width: 550px;margin: auto;margin-top: 200px;">
<input type="text" name="search" id="search" value="" style="width:400px;height: 30px;font-size: 18px;" />
<input type="button" value="搜索" style="height: 30px;width: 100px;"/>
</div>
<!-- 提示语div -->
<div id="dataDiv" style="width: 398px;height: 300px;border: solid 1px black;border-top: none;display: none"></div>
</div>
</body>
</html>
![v2-9a7bbeeba1e7c26332a31e1206327c17_b.jpg](http://img-03.proxy.5ce.com/view/image?&type=2&guid=b2888fa9-1830-eb11-8da9-e4434bdf6706&url=https://pic4.zhimg.com/v2-9a7bbeeba1e7c26332a31e1206327c17_b.jpg)