ajax关键字自动补全
nefu-wangxun 人气:0遇到的小坑
- 回调函数相对window.onload的摆放位置
- 给回调函数addData传数据时,如何操作才能将数据传进去
代码实现
前端代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>ajax实现关键字联想和自动补全</title> <style> *{ margin: 0; padding: 0; box-sizing: border-box; } #keyWords{ margin-top: 10px; margin-left: 10px; width: 300px; height: 25px; font-size: 20px; padding-left: 5px; } #dataDiv{ background-color: wheat; width: 300px; margin-left: 10px; display: none; } #dataDiv p{ padding-left: 10px; padding-top: 7px; padding-bottom: 3px; cursor: pointer; } #dataDiv p:hover{ background-color: cornflowerblue; color: white; } </style> </head> <body> <!-- 需求: 1. 给定文本输入框,显示层,显示层里的显示栏 2. 当用户在文本框里输入数据时,发生keyup事件时,将文本框里的数据,以ajax请求方式提交的到后端 3. 后端对前端提交的关键字,在数据库里进行模糊查询 4. 将后端查询到的数据以json格式传给前端 5. 前端解析后端传来的数据,将数据显示在提示栏里 6. 当用户点击提示中的某条提示信息时,将提示栏里的信息赋给输入框,隐藏提示层 注意:1. 凡是输入框里发生keyup事件时,都要进行ajax请求提交,实时获取提示信息 2. 输入框信息为空时,也要隐藏提示层 --> <script> window.onload = function (){ //获取dom对象 input_txt = document.getElementById("keyWords") div_data = document.getElementById("dataDiv") //为输入框绑定keyup事件 input_txt.onkeyup = function (){ //输入框为空,隐藏提示层 if(this.value.trim() == ""){ div_data.style.display = "none" }else{ //每当keyup时,发送ajax请求,传递文本框内数据 var xmlHttpRequest = new XMLHttpRequest(); xmlHttpRequest.onreadystatechange = function (){ if(this.readyState == 4){ if(this.status == 200){ //解析后端传来的json数据:[{"content" : "data"}, {}, {}] var jsonArray = JSON.parse(this.responseText) var html = "" for(var i = 0; i < jsonArray.length; i++){ var perData = jsonArray[i].content //为p标签绑定单击事件,将数据以字符串的形式传给回调函数 html += "<p onclick='addData(\""+perData+"\")'>"+perData+"</p>" } div_data.innerHTML = html div_data.style.display = "block" }else{ alert("异常状态码: " + this.status) } } } xmlHttpRequest.open("GET", "/ajax/ajaxAutoComplete?keyWords="+this.value+"", true) xmlHttpRequest.send() } } } function addData(perData){ //完成自动补全 input_txt.value= perData //隐藏提示层 div_data.style.display = "none" } </script> <input type="text" id="keyWords"> <div id="dataDiv"> <!-- <p>java</p> <p>jsp</p> <p>service</p> <p>servlet</p> <p>docker</p> <p>linux</p> --> </div> </body> </html>
后端代码
package com.examples.ajax.servlet; import com.alibaba.fastjson.JSON; import com.examples.ajax.beans.KeyWords; import com.examples.ajax.utils.DBUtils; import jakarta.servlet.ServletException; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; @WebServlet("/ajaxAutoComplete") public class AjaxRequest13 extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取前端传来的关键字 String keyWords = request.getParameter("keyWords"); //连接数据库,进行模糊查询 Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; //封装关键字对象 List<KeyWords> keyWordsList = new ArrayList<>(); try { conn = DBUtils.getConnection(); String sql = "select content from tb_search where content like ?"; ps = conn.prepareStatement(sql); ps.setString(1, keyWords + "%"); rs = ps.executeQuery(); while(rs.next()){ String content = rs.getString("content"); //封装成关键字对象 KeyWords keyWordsObj = new KeyWords(content); //将关键字对象封装 keyWordsList.add(keyWordsObj); } } catch (SQLException e) { throw new RuntimeException(e); }finally { DBUtils.close(conn, ps, rs); } //后端数据json化 String jsonKeyWordsArray = JSON.toJSONString(keyWordsList); //返回后端数据 response.getWriter().write(jsonKeyWordsArray); } }
用到的实体类
package com.examples.ajax.beans; public class KeyWords { private String content; public KeyWords() { } public KeyWords(String content) { this.content = content; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } }
自己封装的jdbc工具类
package com.examples.ajax.utils; import java.sql.*; import java.util.ResourceBundle; /** * 封装自己的jdbc工具类 */ public class DBUtils { static ResourceBundle bundle = ResourceBundle.getBundle("jdbc"); static String driver; static String url; static String username; static String password; static { driver = bundle.getString("driver"); url = bundle.getString("url"); username = bundle.getString("username"); password = bundle.getString("password"); try { Class.forName(driver); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } } private DBUtils(){} public static Connection getConnection() throws SQLException { return DriverManager.getConnection(url, username, password); } public static void close(Connection conn, PreparedStatement ps, ResultSet rs){ if(rs != null){ try { rs.close(); } catch (SQLException e) { throw new RuntimeException(e); } } if(ps != null){ try { ps.close(); } catch (SQLException e) { throw new RuntimeException(e); } } if(conn != null){ try { conn.close(); } catch (SQLException e) { throw new RuntimeException(e); } } } }
数据库表:
一张表: tb_search
数据表描述: 除了id, 就一个字段 content varchar(255) not null
效果展示:
自己在远程数据库上用docker运行了一个mysql数据库,查询速度比较慢,但演示关键字联想和自动补全功能的测试目的已经达到
加载全部内容