使用AJAX异步通信技术实现搜索联想和自动补全示例

 更新时间:2023年05月17日 09:24:11   作者:@每天都要敲代码  
这篇文章主要介绍了使用AJAX异步通信技术实现搜索联想和自动补全示例,AJAX是前后台交互的能⼒ 也就是我们客户端给服务端发送消息的⼯具,以及接受响应的⼯具,需要的朋友可以参考下

一:AJAX实现搜索联想和自动补全

(1)实现的原理

什么是搜索联想?自动补全?

①百度是一个很典型的代表。在百度的搜索框中输入相关信息的时候,会有搜索联想以及自动补全。

②搜索联想和自动补全:实际上是为了方便用户的使用,让用户的体验更好。

③搜索联想:当用户输入一些单词之后,自动联想出用户要搜索的信息,给一个提示。

④自动补全:当联想出一些内容之后,用户点击某个联想的单词,然后将这个单词自动补全到搜索框当中。

⑤搜索联想和自动补全功能,因为是页面局部刷新效果,所以需要使用ajax请求来完成。

搜索联想,自动补全功能的核心实现原理?

①当键盘事件发生之后,比如keyup:键弹起事件。

②会发送ajax请求,请求中提交用户输入的搜索内容,例如:北京(发送ajax请求,携带“北京”两个字)。

③后端接收到ajax请求,接收到“北京”两个字,执行select语句进行模糊查询,返回查询结果

④将查询结果封装成json格式的字符串,将json格式的字符串响应到前端。

⑤前端接收到json格式的字符串之后,解析这个json字符串,动态展示页面。 

(2)页面实现

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>ajax实现搜索联想和自动补全功能</title>
    <style type="text/css">
        /* 类选择器,设置input标签,text边框*/
        .userInput {
            width: 300px; /*框宽*/
            height: 25px; /*框高*/
            font-size: 20px; /*里面字大小*/
            padding-left: 5px; /*内补丁,距离框的距离*/
        }
        /*类选择器,设置div的样式*/
        .showDataDiv {
            width: 309px; /*宽度*/
            border: 1px solid lightgray; /*实线边框*/
            background-color: antiquewhite; /*设置背景颜色*/
            display: none; /*设置开始的div是隐藏的,不显示*/
        }
        /*设置p标签*/
        .showDataDiv p {
            padding-left: 5px; /*内补丁,距离框的距离*/
            margin-top: 2px; /*外补丁,p距离顶部的宽度*/
            margin-bottom: 2px; /*外补丁,p距离低部的宽度*/
        }
        /*p标签增加动作,点到其中一个选项变色并变成小手*/
        .showDataDiv p:hover {
            cursor: pointer; /*鼠标变成小手*/
            border: 1px blue solid; /*每选中一行,增加实线边框*/
            background-color: aliceblue; /*设置变换的背景色*/
        }
    </style>
</head>
<body>
<!--文本框-->
<input type="text" class="userInput" id="keywords">
<!--div盒子-->
<div id="datadiv" class="showDataDiv">
<!--<p>北京疫情最新情况</p>
    <p>北京天气</p>
    <p>北京时间</p>
    <p>北京人</p>-->
</div>
</body>
</html>

页面展示

(3)设置数据库表

drop table if exists t_ajax;
create table t_ajax(
    id int primary key auto_increment,
    content varchar(255)
);
insert into t_ajax(content) values('javascript');
insert into t_ajax(content) values('javaweb');
insert into t_ajax(content) values('java');
insert into t_ajax(content) values('java123');
insert into t_ajax(content) values('mysql');
insert into t_ajax(content) values('myweb');
insert into t_ajax(content) values('myapp');
insert into t_ajax(content) values('jdk');
commit;
select * from t_ajax;

效果展示 

(4)前端代码实现

①只要keyup键盘事件发生,就发送Ajax请求,把输入的数据(this.value)发送出去

②首先就要连接数据库进行模糊查询,实现搜索联想功能

③然后我们点击div的<p>标签的内容时,会进行自动补全到文本框

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>ajax实现搜索联想和自动补全功能</title>
    <style type="text/css">
        /* 类选择器,设置input标签,text边框*/
        .userInput {
            width: 300px; /*框宽*/
            height: 25px; /*框高*/
            font-size: 20px; /*里面字大小*/
            padding-left: 5px; /*内补丁,距离框的距离*/
        }
        /*类选择器,设置div的样式*/
        .showDataDiv {
            width: 309px; /*宽度*/
            border: 1px solid lightgray; /*实线边框*/
            background-color: antiquewhite; /*设置背景颜色*/
            display: none; /*设置开始的div是隐藏的,不显示*/
        }
        /*设置p标签*/
        .showDataDiv p {
            padding-left: 5px; /*内补丁,距离框的距离*/
            margin-top: 2px; /*外补丁,p距离顶部的宽度*/
            margin-bottom: 2px; /*外补丁,p距离低部的宽度*/
        }
        /*p标签增加动作,点到其中一个选项变色并变成小手*/
        .showDataDiv p:hover {
            cursor: pointer; /*鼠标变成小手*/
            border: 1px blue solid; /*每选中一行,增加实线边框*/
            background-color: aliceblue; /*设置变换的背景色*/
        }
    </style>
</head>
<body>
<script type="text/javascript">
    window.onload = function() {
        document.getElementById("keywords").onkeyup = function(){
            if (this.value == "") {
                // 如果为空串,就把div隐藏起来
                // 不然查询联想之后,删除查询的内容,下面div还是保持原状
                document.getElementById("datadiv").style.display = "none"
            }else{
                // 发送ajax请求
                // 1. 创建AJAX核心对象
                var xmlHttpRequest = new XMLHttpRequest();
                // 2. 注册回调函数
                xmlHttpRequest.onreadystatechange = function() {
                    if (xmlHttpRequest.readyState == 4) {
                        if (xmlHttpRequest.status >= 200 && xmlHttpRequest.status < 300) {
                            // [{"content":"javascript"},{"content":"javaweb"},{"content":"java..."}]
                            var json = JSON.parse(xmlHttpRequest.responseText);
                            // 遍历数组
                            var html = ""
                            for (var i = 0; i < json.length; i++) {
                                // 点击p标签执行一个回调函数,把内容显示到文本框中
                                html += "<p onclick='setInput(\""+json[i].content+"\")'>"+json[i].content+"</p>"
                            }
                            // 让数据在div展示出来
                            document.getElementById("datadiv").innerHTML = html
                            // 让div显示出来
                            document.getElementById("datadiv").style.display = "block"
                        }
                    }
                }
                // 3. 开启通道,并把数据传过去,连接数据库进行模糊查询
                xmlHttpRequest.open("GET", "/auto_complete/query?_="+new Date().getTime()+"&keywords=" + this.value, true)
                // 4. 发送请求
                xmlHttpRequest.send()
            }
        }
    }
    // 实现自动补全功能
    function setInput(content){
        // 先把数据显示到文本框中
        document.getElementById("keywords").value = content
        // 显示到文本框后,再次把div进行隐藏
        document.getElementById("datadiv").style.display = "none"
    }
</script>
<!--文本框-->
<input type="text" class="userInput" id="keywords">
<!--div盒子-->
<div id="datadiv" class="showDataDiv">
    <!--<p>北京疫情最新情况</p>
    <p>北京天气</p>
    <p>北京时间</p>
    <p>北京人</p>-->
</div>
</body>
</html>

(5)后端代码实现

主要是根据发过来的数据,连接数据库进行模糊查询;把查询结果拼成JSON格式的字符串

package com.bjpowernode.zl;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
@WebServlet("/query")
public class QueryServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 获取用户输入的关键字
        String keywords = request.getParameter("keywords");
        // jdbc代码连接数据库,根据关键字查询数据库,返回数据,拼接json格式的字符串
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        // 拼成JSON格式的字符串
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        try {
            // 注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            // 获取连接
            String url = "jdbc:mysql://localhost:3306/bjpowernode?useUnicode=true&characterEncoding=UTF-8";
            String user = "root";
            String password = "***";
            conn = DriverManager.getConnection(url, user, password);
            String sql = "select content from t_ajax where content like ?"; // 模糊查询的时候,条件不建议使用%开始,因为会让字段上的索引失效,查询效率降低。
            ps = conn.prepareStatement(sql);
            ps.setString(1, keywords + "%");
            rs = ps.executeQuery();
            // [{"content":"javascript"},{"content":"javaweb"},{"content":"java..."}]
            while (rs.next()) {
                String content = rs.getString("content");
                sb.append("{\"content\":\""+content+"\"},");
            }
        }catch(Exception e){
            e.printStackTrace();
        } finally {
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (ps != null) {
                try {
                    ps.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (rs != null) {
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        // 最后会多一个逗号,进行截串
        response.setContentType("text/html;charset=UTF-8");
        response.getWriter().print(sb.subSequence(0, sb.length() - 1) + "]");
    }
}

(6)动图效果展示 

二:HTTP状态信息

1xx: 信息

消息:描述:100 Continue服务器仅接收到部分请求,但是一旦服务器并没有拒绝该请求,客户端应该继续发送其余的请求。101 Switching Protocols服务器转换协议:服务器将遵从客户的请求转换到另外一种协议。

2xx: 成功

消息:描述:200 OK请求成功(其后是对GET和POST请求的应答文档。)201 Created请求被创建完成,同时新的资源被创建。202 Accepted供处理的请求已被接受,但是处理未完成。203 Non-authoritative Information文档已经正常地返回,但一些应答头可能不正确,因为使用的是文档的拷贝。204 No Content没有新文档。浏览器应该继续显示原来的文档。如果用户定期地刷新页面,而Servlet可以确定用户文档足够新,这个状态代码是很有用的。205 Reset Content没有新文档。但浏览器应该重置它所显示的内容。用来强制浏览器清除表单输入内容。206 Partial Content客户发送了一个带有Range头的GET请求,服务器完成了它。

3xx: 重定向

消息:描述:300 Multiple Choices多重选择。链接列表。用户可以选择某链接到达目的地。最多允许五个地址。301 Moved Permanently所请求的页面已经转移至新的url。302 Found所请求的页面已经临时转移至新的url。303 See Other所请求的页面可在别的url下被找到。304 Not Modified未按预期修改文档。客户端有缓冲的文档并发出了一个条件性的请求(一般是提供If-Modified-Since头表示客户只想比指定日期更新的文档)。服务器告诉客户,原来缓冲的文档还可以继续使用。305 Use Proxy客户请求的文档应该通过Location头所指明的代理服务器提取。306 Unused此代码被用于前一版本。目前已不再使用,但是代码依然被保留。307 Temporary Redirect被请求的页面已经临时移至新的url。

4xx: 客户端错误

消息:描述:400 Bad Request服务器未能理解请求。401 Unauthorized被请求的页面需要用户名和密码。402 Payment Required此代码尚无法使用。403 Forbidden对被请求页面的访问被禁止。404 Not Found服务器无法找到被请求的页面。405 Method Not Allowed请求中指定的方法不被允许。406 Not Acceptable服务器生成的响应无法被客户端所接受。407 Proxy Authentication Required用户必须首先使用代理服务器进行验证,这样请求才会被处理。408 Request Timeout请求超出了服务器的等待时间。409 Conflict由于冲突,请求无法被完成。410 Gone被请求的页面不可用。411 Length Required"Content-Length" 未被定义。如果无此内容,服务器不会接受请求。412 Precondition Failed请求中的前提条件被服务器评估为失败。413 Request Entity Too Large由于所请求的实体的太大,服务器不会接受请求。414 Request-url Too Long由于url太长,服务器不会接受请求。当post请求被转换为带有很长的查询信息的get请求时,就会发生这种情况。415 Unsupported Media Type由于媒介类型不被支持,服务器不会接受请求。416服务器不能满足客户在请求中指定的Range头。417 Expectation Failed

5xx: 服务器错误

消息:描述:500 Internal Server Error请求未完成。服务器遇到不可预知的情况。501 Not Implemented请求未完成。服务器不支持所请求的功能。502 Bad Gateway请求未完成。服务器从上游服务器收到一个无效的响应。503 Service Unavailable请求未完成。服务器临时过载或当机。504 Gateway Timeout网关超时。505 HTTP Version Not Supported服务器不支持请求中指明的HTTP协议版本。

到此这篇关于使用AJAX异步通信技术实现搜索联想和自动补全示例的文章就介绍到这了,更多相关AJAX实现搜索联想和自动补全内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • ajax请求json数据案例详解

    ajax请求json数据案例详解

    最近项目有这样一个需求,点击六大洲,出现对应的一些请求信息,展示在下面,当请求之后,第二次点击就不用再次请求了,究竟用代码怎么写呢,下面小编带领大家了解了解
    2015-09-09
  • 如何实现ajax延时发送在空闲之后去发送ajax请求

    如何实现ajax延时发送在空闲之后去发送ajax请求

    关键字搜索的功能,还是比较实用的,在实现过程中就需用到ajax延时发送,下面有个不错的示例,有需要的朋友可以参考下
    2013-12-12
  • ajax的两种提交方式(get/post)和两种版本

    ajax的两种提交方式(get/post)和两种版本

    本篇也用encodeURI对字符串做了加密,并在类里做了解码,其中需要一些注意的地方在源码里做了注释。get/post两种提交方式,但get提交容易乱码,一定多加注意
    2013-09-09
  • Ajax跨域查询完美解决通过$.getJSON()实现

    Ajax跨域查询完美解决通过$.getJSON()实现

    浏览器安全上做了限制,禁止ajax跨域获得数据,可以通过jquery提供的$.getJSON()可以跨域获得JSON格式的数据,具体的实现如下,感兴趣的朋友可以参考下哈,希望对大家有所帮助
    2013-06-06
  • Ajax请求中的异步与同步,需要注意的地方说明

    Ajax请求中的异步与同步,需要注意的地方说明

    默认设置下,所有请求均为异步请求。如果需要发送同步请求,请将此选项设置为 false。注意,同步请求将锁住浏览器,用户其它操作必须等待请求完成才可以执行
    2012-04-04
  • 深入浅析AjaxFileUpload实现单个文件的 Ajax 文件上传库

    深入浅析AjaxFileUpload实现单个文件的 Ajax 文件上传库

    jQuery.AjaxFileUpload.js是一款jQuery插件,用于通过ajax上传文件。本文给大家介绍AjaxFileUpload实现单个文件的 Ajax 文件上传库,对此感兴趣的朋友一起学习吧
    2016-04-04
  • 利用ajax传递数组及后台接收的方法详解

    利用ajax传递数组及后台接收的方法详解

    这篇文章主要给大家介绍了关于利用ajax传递数组及后台接收的相关资料,文中介绍的非常详细,对大家具有一定的参考学习价值,需要的朋友们下面跟着小编一起来学习学习吧。
    2017-06-06
  • 基于firefox实现ajax图片上传

    基于firefox实现ajax图片上传

    这篇文章主要介绍了基于firefox实现ajax图片上传,大家都知道在FF下使用ajax是件挺困难的事情,今天给大家介绍的是完美解决这个问题的方法,小伙伴可以参考下。
    2015-05-05
  • Ajax获取到数据放入echarts里不显示的原因分析及解决办法

    Ajax获取到数据放入echarts里不显示的原因分析及解决办法

    在做一个需要用到echarts地图的项目的时候,成功通过ajax获取到了后台提供的数据,并生成了想要的JSON串。但是,放到echarts option.series[0].data里,获取不到数据。在生成的地图上无法看到你从后台获取到的值,下面小编给大家分享我的解决办法,需要的朋友参考下
    2016-01-01
  • Ajax实现动态加载组合框的实例代码

    Ajax实现动态加载组合框的实例代码

    本文通过实例代码给大家介绍了Ajax实现动态加载组合框功能,感兴趣的朋友一起看看吧
    2017-08-08

最新评论