很久以前就写好的一个小demo,最近又拿出来整理、修改了一下
找到百度的API
首先得找到百度的API,我们假定去百度搜索我的名字Alkali
(这不叫阿卡丽!不信看这里),然后得到如下页面
可以在控制台的Network里看到这么一个信息
从中提取出请求地址,掐头去尾缩减掉我们不需要的参数,这样我们就得到以下API:
这里的wd
就是我们请求的关键字,cb
即回调函数。
调用API实现联想搜索
首先先讲一下JSONP的原理,即本地动态的创建<script>
标签,地址指向第三方API,并允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。
我们再来看看刚刚搜的Alkali
的preview
可以看到我们所需数据存放在json.s
里
根据以上原理,我们可以先写个雏形
1 | input.addEventListener('keyup', function(){ |
上面的代码已经可以实现了联想搜索,不过还有一定的瑕疵。可以看到我使用的是循环插入dom,这样在需要大量操作dom时,性能上就会不尽人意。不过这里为了方便我就先这么写了→_→。可以使用innerHtml的方法来添加:
1 | var htmlText = ''; |
除此之外我们还需要针对中文将input里的值在请求之前进行转义。
1 | var val = encodeURI(input.value);//将value进行转义之后再进行请求 |
这里使用的encodeURI()是Javascript中真正用来对URL编码的函数。使用方法大致如下:
1 | encodeURI('我');//"%E6%88%91" |
再有,我们绑定的是input框的 keyup
事件,但是有很多keyup触发的时候我们并不希望或者并不需要触发insert函数,所以我们可以对input的value值进行对比,如果值没有发生改变则不必进行之后的一系列操作。
1 | var oldVal;//定义一个存放旧value的变量 |
想要简单点的话也可以绑定 input
事件:
1 | input.addEventListener('input', function(){ |
为了使用方便,封装成函数是最好不过的选择:
1 | function jsonp(objects){ |
下面是我最后使用的js代码:
1 | ;(function(){ |
注意上面的window[callbackName] = function(){};
因为我用立即执行函数包裹住了所有的代码,使得回调函数没有暴露在全局作用域里,而jsonp只在window下调用callback函数,所以需要将jsonp函数里的回调函数写为window的方法,大概就是这样😑
说了这么多,是时候放出没有任何css样式的demo了,外貌协会请轻喷。。