zoukankan      html  css  js  c++  java
  • 案例:搜索框内容自动提示

    实现功能如下:

    1. 获取搜索框并为其添加用户输入事件
    2. 获取用户输入的关键字
    3. 向服务器端发送请求并携带关键字作为请求参数
    4. 将响应数据显示在搜索框底部

    搜索框输入自动提示接口:

    • 简要描述
      • 根据用户在文本框中输入的关键字,匹配相关内容
    • 请求地址
      • /searchAutoPrompt
    • 请求方式
      • GET
    • 参数
    参数名 必选 类型 说明
    key string 用户输入的关键字
    • 返回值
    [
        'ajax同步异步',
        'ajax教程',
        '$.ajax()方法详解'
    ]

    该案例有个问题:比如说输入Ajax

    第一次发送请求的时候携带的参数是A

    第二次发送请求的时候携带的参数是AJ

    第三次发送请求的时候携带的参数是AJA

    即使使用的是中文输入法,在输入拼音的时候,拼音也被发送到了服务器端,这是不合理的,这无形当中发送了很多无意义的请求

    如何保证在用户输入完成之后,再向服务器端发送请求呢?

    在用户连续输入的情况下,输入字符的速度是比较快的,两个字符之间的时间间隔是比较短的,我们可以利用这个时间间隔来解决这个问题。

    具体怎么做呢?

    在oninput事件触发的时候,在请求的外部包裹一层延迟定时器,让请求不要立即发送。

    由于用户是连续输入,oninput事件会被不断触发。当再一次触发oninput事件的时候,先将上一次开启的延迟定时器清除,定时器清除了请求也就不会发送,这就保证了上一次的输入不会有请求发送。然后再开启一个新的定时器,用于当前这一次的输入发送请求。循环往复,直到用户输入完成才会发送一次请求。实际上,每次的输入都会清除上一次的定时器,这就大大减少了无意义请求的次数。

    第二个问题:当我们把搜索框中的文字清除掉的时候,下面的相关内容并没有被清空,但实际上搜索提示框是不应该显示的。

    解决方案:当搜索框的内容为空时,隐藏提示框。

    <!-- 引入bootstrap样式文件 -->
    <link rel="stylesheet" href="/assets/bootstrap/dist/css/bootstrap.min.css">
    <!-- css样式 -->
    <style type="text/css">
        .container {
            padding-top: 150px;
        }
        .list-group {
            display: none;
        }
    </style>
    <!-- 页面布局 -->
    <div class="container">
        <div class="form-group">
            <input type="text" class="form-control" placeholder="请输入搜索关键字" id="search">
            <ul class="list-group" id="list-box">
            </ul>
        </div>
    </div>

    引入自己封装好的ajax.js文件:

    <script type="text/javascript">
            function ajax (options) {
                // 存储的是默认值
                var defaults = {
                    type: 'get',
                    url: '',
                    data: {},
                    header: {
                        'Content-Type': 'application/x-www-form-urlencoded'
                    },
                    success: function () {},
                    error: function () {}
                };
    
                // 使用options对象中的属性覆盖defaults对象中的属性
                Object.assign(defaults, options);
    
                // 创建ajax对象
                var xhr = new XMLHttpRequest();
                // 拼接请求参数的变量
                var params = '';
                // 循环用户传递进来的对象格式参数
                for (var attr in defaults.data) {
                    // 将参数转换为字符串格式
                    params += attr + '=' + defaults.data[attr] + '&';
                }
                // 将参数最后面的&截取掉 
                // 将截取的结果重新赋值给params变量
                params = params.substr(0, params.length - 1);
    
                // 判断请求方式
                if (defaults.type == 'get') {
                    defaults.url = defaults.url + '?' + params;
                }
                /*
                    {
                        name: 'zhangsan',
                        age: 20
                    }
                    name=zhangsan&age=20
                 */
    
                // 配置ajax对象
                xhr.open(defaults.type, defaults.url);
                // 如果请求方式为post
                if (defaults.type == 'post') {
                    // 用户希望的向服务器端传递的请求参数的类型
                    var contentType = defaults.header['Content-Type']
                    // 设置请求参数格式的类型
                    xhr.setRequestHeader('Content-Type', contentType);
                    // 判断用户希望的请求参数格式的类型
                    // 如果类型为json
                    if (contentType == 'application/json') {
                        // 向服务器端传递json数据格式的参数
                        xhr.send(JSON.stringify(defaults.data))
                    }else {
                        // 向服务器端传递普通类型的请求参数
                        xhr.send(params);
                    }
    
                }else {
                    // 发送请求
                    xhr.send();
                }
                // 监听xhr对象下面的onload事件
                // 当xhr对象接收完响应数据后触发
                xhr.onload = function () {
    
                    // xhr.getResponseHeader()
                    // 获取响应头中的数据
                    var contentType = xhr.getResponseHeader('Content-Type');
                    // 服务器端返回的数据
                    var responseText = xhr.responseText;
    
                    // 如果响应类型中包含applicaition/json
                    if (contentType.includes('application/json')) {
                        // 将json字符串转换为json对象
                        responseText = JSON.parse(responseText)
                    }
    
                    // 当http状态码等于200的时候
                    if (xhr.status == 200) {
                        // 请求成功 调用处理成功情况的函数
                        defaults.success(responseText, xhr);
                    }else {
                        // 请求失败 调用处理失败情况的函数
                        defaults.error(responseText, xhr);
                    }
                }
            }
    
            ajax({
                type: 'post',
                // 请求地址
                url: 'http://localhost:3000/responseData',
                success: function (data) {
                    console.log('这里是success函数');
                    console.log(data)
                }
            })
            /*
                请求参数要考虑的问题
                    1.请求参数位置的问题
                        将请求参数传递到ajax函数内部, 在函数内部根据请求方式的不同将请求参数放置在不同的位置
                        get 放在请求地址的后面
                        post 放在send方法中
                    2.请求参数格式的问题
                        application/x-www-form-urlencoded
                            参数名称=参数值&参数名称=参数值
                            name=zhangsan&age=20
                        application/json
                            {name: 'zhangsan', age: 20}
                        1.传递对象数据类型对于函数的调用者更加友好
                        2.在函数内部对象数据类型转换为字符串数据类型更加方便
            */
    </script>
    <script src="/js/ajax.js"></script>
    <!-- 引入下载好的模板引擎文件, 下载网址:https://aui.github.io/art-template/zh-cn/index.html -->
    <script src="/js/template-web.js"></script>
    <!-- 模板 -->
    <script type="text/html" id="tpl">
        {{each result}}
            <li class="list-group-item">{{$value}}</li>
        {{/each}}
    </script>
    <!-- JS逻辑代码 -->
    <script>
        // 获取搜索框
        var searchInp = document.getElementById('search');
        // 获取提示文字的存放容器
        var listBox = document.getElementById('list-box');
        // 存储定时器的变量
        var timer = null;
        // 当用户在文本框中输入的时候触发
        searchInp.oninput = function () {
            // 清除上一次开启的定时器
            clearTimeout(timer);
            // 获取用户输入的内容
            var key = this.value;
            // 如果用户没有在搜索框中输入内容
            if (key.trim().length == 0) {
                // 将提示下拉框隐藏掉
                listBox.style.display = 'none';
                // 阻止程序向下执行
                return;
            }
            // 开启定时器 让请求延迟发送
            timer = setTimeout(function () {
                // 向服务器端发送请求
                // 向服务器端索取和用户输入关键字相关的内容
                ajax({
                    type: 'get',
                    url: 'http://localhost:3000/searchAutoPrompt',
                    data: {
                        key: key
                    },
                    success: function (result) {
                        // 使用模板引擎拼接字符串
                        var html = template('tpl', {result: result});
                        // 将拼接好的字符串显示在页面中
                        listBox.innerHTML = html;
                        // 显示ul容器
                        listBox.style.display = 'block';
                    }
                })
            }, 800)
        }
    </script>
  • 相关阅读:
    5.对象的简化属性
    7.函数参数默认值
    python中argparse
    VC 6.0 打开文件出错
    【UNIX程序设计教程】 阅读初体验(1)
    引以为鉴ARM开发板连线注意事项
    windows xp宿主机 + Linux 虚拟机 网络配置
    Gcc编译选项分析
    ADS下调试出现的警告信息
    S3C2440串口通讯实现
  • 原文地址:https://www.cnblogs.com/zcy9838/p/13057126.html
Copyright © 2011-2022 走看看