zoukankan      html  css  js  c++  java
  • 使用jsonp跨域调用百度js实现搜索框智能提示,并实现鼠标和键盘对弹出框里候选词的操作【附源码】

    项目中常常用到搜索,特别是导航类的网站。自己做关键字搜索不太现实,直接调用百度的是最好的选择。
    使用jquery.ajax的jsonp方法可以异域调用到百度的js并拿到返回值,当然$.getScript也可以实现跨域调用js。

    jsonp快速入门:
    【原创】说说JSON和JSONP,也许你会豁然开朗,含jQuery用例
    关于jquery.ajax的jsonp方法是用以及其error回调函数不能正确执行,请参考园长dudu的文章:
    jquery ajax中使用jsonp的限制
    jQuery插件jQuery-JSONP使用注意
    其他有关jsonp的文章:
    利用iframe实现ajax 跨域通信的解决方案

    ok,了解了jsonp的原理和应用后,我们看看百度的智能提示是如何做的
    在chrome的调试窗口下看看百度搜索发出的请求。当输入关键字“a”,请求如图:

    用firebug看下请求的参数,如图:


    请求方式:get请求
    请求参数:wd明显是要搜索的关键字;cb是请求回来的处理函数,名字可以随便给;t是时间戳,防止缓存的;p不知道什么意思,每次请求都给3就可以了;sid也不知道什么意思,不要也可以请求,如果想要也可以带上,值就是上面截图的值。

    请求地址和参数都知道了,于是写下如下js测试是否可以拿到关键字提示(源码里的test.html页面):

    var qsData = { 'wd': ‘a’, 'p': '3', 'cb': 'getData', 't': new Date().getMilliseconds().toString() };
         $.ajax({
              async: false,
              url: "http://suggestion.baidu.com/su",
              type: "GET",
              dataType: 'jsonp',
              jsonp: 'jsoncallback',
              data: qsData,
              timeout: 5000,
              success: function (json) {
              },
              error: function (xhr) {
              }
        });

    qsData封装所有请求要发送的参数;getData是自定义的名称,用于处理返回的关键字(以下示例代码把请求回来的关键字打印到了FireBug的控制台):

            function getData(data) {
                var Info = data['s'];  //获取异步数据
                console.log(Info);
            }

    监控下文本框,实时的发送ajax请求并拿回数据是这样的:

    ok,测试可用,的确可以拿到关键字提示。但是总不能把一堆关键字放到前台让用户看,至少得跟百度一样,可以用鼠标和键盘方向键从候选词框里选词吧。
    最关键的来了,现在开始写完整的智能提示并配合鼠标和键盘对候选词的操作(源码里的index.html页面),实现如下功能:

    1. 即时监控字母键和数字键,按下就发ajax请求(也可以设置延迟发请求,源码里有);同时监控空格、退格、Delete、Enter等键;
    2. 鼠标移入弹出层高亮选中的行,点击可上屏;
    3. 按键盘上下方向键可以选择候选词,回车提交跳转到百度搜索页面;
    4. 点击页面其他部位自动隐藏弹出框;
    5. 按ESC键隐藏弹出框

     监控鼠标和键盘输入的js(autoComplete.js 源码里有更详细的注释):

    var timeoutId;   //延迟请求服务器
    var highlightindex = -1;   //高亮标记
    $(function () {
        $("#searchText").keyup(function (event) {
            var myEvent = event || window.event;
            var keyCode = myEvent.keyCode;
            //console.log(keyCode);
    
            //监控键盘
            if (keyCode >= 65 && keyCode <= 90 || keyCode >= 48 && keyCode <= 57 || keyCode >= 96 && keyCode <= 111 || keyCode >= 186 && keyCode <= 222 || keyCode == 8 || keyCode == 46 || keyCode == 32 || keyCode == 13) {
                //延时操作
                //clearTimeout(timeoutId);
                //timeoutId = setTimeout(function () {
                //            timeoutId = FillUrls();
                //             }, 500)
                FillUrls();  //异步请求
                if (highlightindex != -1) {
                    highlightindex = -1;
                }
            }
            else if (keyCode == 38 || keyCode == 40) {
                if (keyCode == 38) {       //向上
                    var autoNodes = $("#auto").children("div")
                    if (highlightindex != -1) {
                        autoNodes.eq(highlightindex).css("background-color", "white");
                        highlightindex--;
                    } else {
                        highlightindex = autoNodes.length - 1;
                    }
                    if (highlightindex == -1) {
                        highlightindex = autoNodes.length - 1;
                    }
                    autoNodes.eq(highlightindex).css("background-color", "#ebebeb");
                    var comText = autoNodes.eq(highlightindex).text();
                    $("#searchText").val(comText);
                }
                if (keyCode == 40) {    //向下
                    var autoNodes = $("#auto").children("div")
                    if (highlightindex != -1) {
                        autoNodes.eq(highlightindex).css("background-color", "white");
                    }
                    highlightindex++;
                    if (highlightindex == autoNodes.length) {
                        highlightindex = 0;
                    }
                    autoNodes.eq(highlightindex).css("background-color", "#ebebeb");
                    var comText = autoNodes.eq(highlightindex).text();
                    $("#searchText").val(comText);
                }
            } else if (keyCode == 13) {     //回车
                if (highlightindex != -1) {
                    var comText = $("#auto").hide().children("div").eq(highlightindex).text();
                    highlightindex = -1;
                    $("#searchText").val(comText);
                } else {
                    $("#auto").hide();
                    $("#searchText").get(0).blur();
                }
            } else if (keyCode == 27) {    //按下Esc 隐藏弹出层
                if ($("#auto").is(":visible")) {
                    $("#auto").hide();
                }
            }
        });

    最后实现效果展示。可以鼠标选择候选词也可以键盘方向键选择,点击即可上屏,回车直接跳到百度页面:

    源码:点击下载

    在线演示地址:点击跳转

  • 相关阅读:
    python--列表,元组,字符串互相转换
    10月清北学堂培训 Day 2
    10月清北学堂培训 Day 1
    网络流小结
    P1850 换教室
    P1948 [USACO08JAN]电话线Telephone Lines
    P3147 [USACO16OPEN]262144
    8月清北学堂培训 Day 7
    8月清北学堂培训 Day3
    8月清北学堂培训 Day1
  • 原文地址:https://www.cnblogs.com/oppoic/p/baidu_auto_complete.html
Copyright © 2011-2022 走看看