本文介绍如何利用jQuery的JSONP机制跨域调用百度智能提示接口。通过解析GET请求参数,封装wd、cb等字段,结合keyup事件监听与键盘鼠标交互逻辑,实现具备高亮选中、方向键导航及回车提交功能的完整搜索建议组件。
JSONP跨域调用原理
在各类项目中,搜索功能尤为常见,尤其是对于导航类网站而言。自行构建关键字搜索库成本较高且效果有限,因此直接调用百度的搜索接口是更为理想的选择。
掌握JSONP原理后,我们可以进一步探讨如何实现百度的智能提示功能。通过Chrome浏览器的开发者工具观察百度搜索发出的请求,当输入关键字“a”时,请求情况如下所示。

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

该请求采用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请求并获取数据的过程如下所示。

完整智能提示功能开发
测试结果表明该方案可行,确实能够获取到关键字提示。然而,直接将所有候选词展示给用户体验不佳,至少应像百度那样,支持通过鼠标点击或键盘方向键从候选词列表中选取。接下来将编写完整的智能提示功能,并配合鼠标与键盘操作实现以下功能: 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();
}
}
});
最终实现的效果展示如下:既可以通过鼠标选择候选词,也可以使用键盘方向键进行选择,点击即可上屏,按回车键则直接跳转至百度页面。

源码下载地址:http://xiazai.jb51.net/201608/yuanma/baidusearch(jb51.net).rar
以上就是本文的全部内容,希望对读者的学习有所帮助,也欢迎大家多多支持本站。