jsonp跨越请求百度搜索api 实现下拉列表提示
题目来源:
最近在做百度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事件)移动选中下拉提示的时候,移出文本框的绑定事件,当鼠标抬起的时候我又
重新绑定事件,好机智有木有!
6、如何按enter打开搜索结果页?
浏览器对超链接有默认行为,不需要单独添加enter事件,在获取数据页面渲染的时候,对a的地址进行赋值,地址是https://www.baidu.com/s?wd=keyword
说明:限于篇幅,事件绑定,事件移除的代码在这就没有贴了。本人大三,经验略浅,欢迎各位大牛指正。
附上百度ife前端技术学院地址:https://github.com/baidu-ife/ife/tree/master/task/task0002
jsonp跨越请求百度搜索api 实现下拉列表提示的更多相关文章
- Ajax跨域:Jsonp实例--百度搜索框下拉提示
Ajax跨域:Jsonp实例--百度搜索框下拉提示 一.总结 一句话总结:a.找好接口:b.用script标签的src引入文件(json数据):c.定义及实现上一步引入文件中的函数 1.如何找到一个网 ...
- 百度地图api 实例 自动提示 并计算两地的行驶距离
百度地图api 实例 自动提示 并计算两地的行驶距离 <!DOCTYPE html> <html> <head> <meta http-equiv=" ...
- jsonp模拟获取百度搜索相关词汇
随便写了个jsonp模拟百度搜索相关词汇的小demo,帮助新手理解jsonp的用法. <!DOCTYPE html><html lang="en">< ...
- vue-resource: jsonp请求百度搜索的接口
1. yarn add vue-resource 2. main.js引入vue-resource import Vue from 'vue' import MintUI from 'mint-ui' ...
- 百度搜索API v3版本与soap
技术文档请参考http://dev2.baidu.com/docs.do?product=2#page=File,和http://dev2.baidu.com/docs.do?product=2#pa ...
- 前端ajax请求百度地图api
$.ajax({ type: "get", url: 'http://api.map.baidu.com/place/v2/search', data:{ ak:'您的ak', q ...
- 【javascript】jquery jsonp跨越请求
<html> <head> <meta charset="utf-8"> <title></title> <scr ...
- typecho博客组插件:openSug.js百度搜索框下拉提示免费代码
Typecho候选搜索增强插件:安装openSug插件即可获得带有“搜索框提示”功能的搜索框,让Typecho搜索更便捷! 支持百度.谷歌.雅虎.Yandex.360好搜.UC神马.酷狗.优酷.淘 ...
- z-blog博客组插件openSug.js百度搜索下拉框提示代码
z-blog安装openSug插件即可获得带有“搜索框提示”功能的搜索框,让z-blog搜索更便捷! https://www.opensug.org/.../opensug_z-blog_v1.0 ...
随机推荐
- 为什么iphone手机比android手机流畅
作为当下最流行.市场占用份额最大的两大手机操作系统IOS和android,目前两者加起来的市场占用率达到90%.我曾经一直用android手机,没有用过iphone,那时候正直iphone4和ipho ...
- java String和Date转换
SimpleDateFormat函数语法: G 年代标志符 y 年 M 月 d 日 h 时 在上午或下午 (1~12) H 时 在一天中 (0~23) m 分 s 秒 S 毫秒 ...
- HttpRuntime.Cache 失效
最近做一个报纸内容类网站,为了提高响应速度,将首页各栏目以及二级栏目中Part文献列表存储在HttpRuntime.Cache缓存中,发布后发现问题,刚插入的缓存很快就失效,本机调试没有问题. 由于H ...
- 纯CSS打造Flow-Steps导航
几个要点: 1.三角箭头效果是用border实现的,详细的可以google下CSS 三角 2.IE6下不支持border-color:transparent(透明),解决方法是先将其设置为一个不常用的 ...
- ARM&Linux 下驱动开发第三节
后台驱动代码如下:比较昨天的,添加了读写指针位置移动操作 #include<linux/init.h> #include<linux/module.h> #include< ...
- bzoj 1041: [HAOI2008]圆上的整点 数学
1041: [HAOI2008]圆上的整点 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/ ...
- 微信公共服务平台开发(.Net 的实现)7-------发送图文消息
之前我们讲过让微信发送给我们普通的文本信息,下面我们来看看如何发送图文信息,需要注意的是这里说的是,让微信发给我们,而不是我们拍个图片发给微信处理,我们上传图片在以后的章节介绍.下面是发送图文消息的函 ...
- Python 读写文件和file对象(转)
1.open使用open打开文件后一定要记得调用文件对象的close()方法.比如可以用try/finally语句来确保最后能关闭文件. file_object = open('thefile.txt ...
- jQuery代码性能小细节
选择器Selector的使用 $("#id")使用id来定位DOM元素无疑是最佳提高性能方式,因为jQuery底层将直接调用本地方法document.getElementbyId( ...
- 使用NIO提升性能
NIO是New I/O的简称,与旧式的基于流的I/O方法相对,从名字看,它表示新的一套Java I/O标准. 具有以下特性: 传统Java IO,它是阻塞的,低效的.那么Java NIO和传统Java ...