基于jQuery JSONP实现百度智能搜索提示功能

作者:桌面漫游时间:2026-10-30 12:44:15浏览:118

本文介绍如何利用jQuery的JSONP机制跨域调用百度智能提示接口。通过解析GET请求参数,封装wd、cb等字段,结合keyup事件监听与键盘鼠标交互逻辑,实现具备高亮选中、方向键导航及回车提交功能的完整搜索建议组件。

JSONP跨域调用原理

在各类项目中,搜索功能尤为常见,尤其是对于导航类网站而言。自行构建关键字搜索库成本较高且效果有限,因此直接调用百度的搜索接口是更为理想的选择。

掌握JSONP原理后,我们可以进一步探讨如何实现百度的智能提示功能。通过Chrome浏览器的开发者工具观察百度搜索发出的请求,当输入关键字“a”时,请求情况如下所示。

JSONP跨域调用原理

借助Firebug工具查看具体的请求参数,具体细节如图所示。

JSONP跨域调用原理

该请求采用GET方式。其中,参数wd代表待搜索的关键字;cb指定了接收返回数据时调用的回调函数名称,可自定义;t为当前时间戳,用于防止浏览器缓存;p参数的具体含义不明,但每次请求固定传值3即可;sid参数非必需,若需传递可沿用截图中所示的值。

基础请求测试实现

明确了请求地址与参数结构后,编写如下JavaScript代码以测试能否成功获取关键字提示(相关源码位于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请求并获取数据的过程如下所示。

JSONP跨域调用原理

完整智能提示功能开发

测试结果表明该方案可行,确实能够获取到关键字提示。然而,直接将所有候选词展示给用户体验不佳,至少应像百度那样,支持通过鼠标点击或键盘方向键从候选词列表中选取。接下来将编写完整的智能提示功能,并配合鼠标与键盘操作实现以下功能: 1. 实时监控字母键和数字键,按下即发送AJAX请求(源码中也可设置延迟发送);同时监控空格、退格键、Delete键、Enter键等; 2. 鼠标移入弹出层时高亮显示当前行,点击即可上屏; 3. 通过键盘上下方向键选择候选词,按回车键提交并跳转至百度搜索页面; 4. 点击页面其他区域时自动隐藏弹出框; 5. 按ESC键隐藏弹出框。

以下是监控鼠标和键盘输入的JavaScript代码(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();
   }
  }
 });

最终实现的效果展示如下:既可以通过鼠标选择候选词,也可以使用键盘方向键进行选择,点击即可上屏,按回车键则直接跳转至百度页面。

JSONP跨域调用原理

源码下载地址:http://xiazai.jb51.net/201608/yuanma/baidusearch(jb51.net).rar

以上就是本文的全部内容,希望对读者的学习有所帮助,也欢迎大家多多支持本站。

作者最新文章