zoukankan      html  css  js  c++  java
  • 百度搜索下拉提示框实现

        最近在做百度IFE前端技术学院的题,然后有一题就是模拟百度搜索智能提示。题目是开源的,稍后给出地址。

        因为博主没学过后端啊,欲哭无泪,所以不能实现后端模糊搜索,那如果前端ajax纯粹请求一份同样的数据,效果就不好。

        机智的博主直接把百度搜索api借来一下。

        直接从开发者工具,监控网络,找到请求地址。

      百度api:

        我把api缩减了一下,删除了大部分暂时用不上的参数。

        https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=abc&json=1&p=3&cb=Aralic&t

    参数
    wd 关键字
    json 1
    p 3
    cb 回调函数

      参数说明:

          在这里只需要关注两个参数,第一个就是要请求的关键字,第二个是回调函数。相信太多人都了解jsonp,全称是json with padding。如果有不熟悉的,可以从园子里面看看其他大牛的博客先了解一下。

      html代码:

    <div id="container">
            <input type="text" id="kw">
            <ol id="dataList">
            </ol>
    </div>

      javascript 部分:

      问题和功能实现大致分为六部分:

        1、什么时候请求数据或者触发请求数据的条件是什么?

        2、怎么去请求数据?

        3、数据怎么格式处理?

        4、处理的数据怎么放到页面中?

        5、实现键盘上下按键切换下拉提示

        6、enter按键打开新页面,跳转到搜索结果

       解决方案:

        1、我能说针对问题1我就去查资料了吗?

          在input搜索内,可以添加的键盘事件按时间分别为onkeydown<onkeypress<onkeyup. 如果不通过判断输入的键值码,那么为了得到搜索框内刚输入的值,就只能用onkeyup事件了,不然无法获取刚刚输入的值。

        2、请求数据方法,激动人心的时刻到了,到贴代码了。

    技术分享
    //按键抬起事件
    function getData() {
        //下拉提示列表
        var oDataList = $(‘#dataList‘);
        //搜索框
        var sInput = $(‘#kw‘);
        var oldValue = null;
        //当前文本框的值不为空 且和之前不相同
        if (sInput.value != ‘‘ && sInput.value != oldValue) {
            //创建script标签
            var oScript = document.createElement(‘script‘);
            //获取时间戳
            var oTime = new Date().getTime()
            oScript.src = ‘https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=‘+(sInput.value)+‘&json=1&p=3&cb=Aralic&oTime‘;
            document.body.appendChild(oScript);
        } else if (sInput.value == ‘‘) {
            // 如果文本框值为空 清除oDataList的内容并隐藏
            oDataList.style.display = ‘none‘;
            oDataList.innerHTML = "";
        } 
        oldValue = sInput.value;
    }
    技术分享

        3、数据的处理,这是jsonp请求的数据,所以需要在全局新建一个一个函数。参数为data(jsonp发送来的数据);

          可以直接从chrome开发者工具,网络下找到请求,然后右侧有个Preview可以预览返回的数据,当然也有更简单的一个格式化方法

          直接在函数里面控制台打印数据,这样阅读格式化的数据了。

           技术分享

          技术分享

          返回了一个json数据,q表示搜索关键字,s是数组类型,返回的匹配值。

          4、数据的处理并且添加到页面中。

    技术分享
    //jsonp的回调函数
    function Aralic(data) {
        console.log(data);
        var oDataList = $(‘#dataList‘);
        var sInput = $(‘#kw‘);
        var str = ‘‘;
        var iNow = -1;
       
        //当有数据返回时
        if (data.s.length) {
            //拼接字符串
            for (var i = 0; i<data.s.length; i++) {
                str += ‘<li><a href="https://www.baidu.com/s?wd=‘+data.s[i]+‘" target=_blank>‘+data.s[i]+‘</a></li>‘;
            }
            oDataList.style.display = ‘block‘;
            oDataList.innerHTML = str;
    
            //↑ ↓ 两个按键事件
            document.onkeydown = function(ev) {
    
                var ev = ev || window.event;
                var aLi = oDataList.getElementsByTagName(‘li‘);
                //↓键
                if (ev.keyCode == 40) {
    
                    for (var i = 0; i<aLi.length; i++) {
                        aLi[i].className = ‘‘;
                    }
    
                    iNow ++;
                    if (iNow == aLi.length) {
                        iNow = 0;
                    }
                    //移除给文本框的绑定事件
                    removeEvent(sInput, ‘keyup‘, getData);
                    sInput.value = data.s[iNow];
                    aLi[iNow].className = "active";
    
                } else if (ev.keyCode == 38) {
    
                    for (var i = 0; i<aLi.length; i++) {
                        aLi[i].className = ‘‘;
                    }
                    
                    iNow = iNow -1;
                    if (iNow == -1) {
                        iNow = aLi.length - 1;
                    }
    
                    removeEvent(sInput, ‘keyup‘, getData);
                    sInput.value = data.s[iNow];
                    aLi[iNow].className = "active";
                }
                
                document.onkeyup = function() {
                    //重新绑定事件
                    addEvent(sInput, ‘keyup‘, getData);
                }
    
            }
            //无数据返回时候 ul内容置空并隐藏
        } else {
            oDataList.style.display = ‘none‘;
            oDataList.innerHTML = "";
        }   
    }
    技术分享

        5、按键的上下移动控制下拉提示列表。中间出了一个问题,困扰我好长时间。

         最开始,我给输入框一个键盘抬起事件,如果当前输入框的值改变,那么我去请求新数据。

         然后我实现键盘控制下拉提示列表,并同时把选中的下拉提示列表更新到输入框中。诡异的事情发生了,文本框的值只要一改变,立马请求新数据

      下拉提示列表重新被渲染,我去百度首页看百度的效果,上下按键控制更新到输入框的值并不会重新去请求数据。

         后来仔细分析找到原因了,因为焦点还在输入框里面,并且上下按键虽然是给document绑定的事件,但是盖不住事件捕捉啊。所以文本框的值也被改变了。

      鉴于此,我对文本框的按键抬起事件进行了绑定,当触发按键上下键(onkeydown事件)移动选中下拉提示的时候,移出文本框的绑定事件,当鼠标抬起的时候我又

      重新绑定事件,好机智有木有!

  • 相关阅读:
    Zend Framework 入门(2)—多国语言支持
    Zend Framework 入门(1)—快速上手
    国外主流PHP框架比较
    PHP经验集锦
    PHP的GD库函数大全
    最好最实用的PHP二次开发教程
    我的ECshop二次开发从零开始
    Java中实现复制文件或文件夹
    matlab中freqz的用法以及多项式的展开
    matlab滤波器的设计
  • 原文地址:https://www.cnblogs.com/skying555/p/4828736.html
Copyright © 2011-2022 走看看