转:JS实现仿百度搜索框(实时返回搜索建议项)

您所在的位置:网站首页 html5搜索框跳转页面 转:JS实现仿百度搜索框(实时返回搜索建议项)

转:JS实现仿百度搜索框(实时返回搜索建议项)

2023-10-27 03:07| 来源: 网络整理| 查看: 265

实现原理

向输入框动态输入时关键词,将当前关键词作为问号参数后面的值,因为要跨域使用百度的接口,所以通过 JSONP 跨域创建 Ajax 请求。回调函数处理返回值。

尝试研究了一下百度的接口,发现原生的 XHR 接口参数有点复杂(百度应该是考虑了很多情况)。

找了一个 2345 导航,在输入框随便输入一个字母 s,打开 Network,发现它也是向百度的一个地址发送了请求,其中问号后面的‘&wd=s’发送的就是此关键词,’&cb='应该就是回调处理函数,并且它的 Type 也是 script,2345 导航应该也是通过 JSONP 向百度获取数据的

1 var script = document.createElement("script"); 2 script.src = 3 "https://www.baidu.com/su?&wd=" + 4 encodeURI(this.value.trim()) + 5 "&p=3&cb=handleSuggestion"; 6 document.body.appendChild(script);

点开那条请求,果然在里面看到了返回的数据。返回的结果是以一个对象的形式返回的。q 对应着检索关键词,s 对应着返回的结果(数组形式)

后续只需要动态创建 li 标签,设置里面的内容,以及注意其他细节问题。

1.使用 flex 布局实现搜索框的水平垂直居中。

坑 设置完 flex 属性之后发现并没有水平垂直居中,当时设置了父盒子 height:100%,发现如果将 height 设置成具体值就可以实现居中。怀疑是设置了%高度无效,查了一下,高度百分比是相对于父盒子的,也就是 body。默认 html 和 body 是没有设置 height 的。另外,在布局中对于没有设置宽高的块状盒子,宽度默认是 100%的,高度是由里面的内容自然撑开的。

2.先获取常用的 DOM 节点,避免后续频繁查询操作 DOM。

3.为了避免在输入过程中频繁发送请求(如果打字速度快),对请求函数做了函数节流,调了一下间隔 130ms 差不多正好,时间再长就会有卡顿的感觉。使用了 ES6 中的箭头函数避免了 setTimeout 中 this 指向的问题。

4.在回调函数中:

每一次执行时首先要清除建议框里的内容,不然上一次的结果还会存在建议框里!截取了结果中的前五个(如果把所有结果都展示出来感觉有点丑…百度官方是展示前四个搜索建议)

结果处理完毕后,执行自执行匿名函数,删除创建的 script 标签;

5.由于 li 是动态创建的,点击 li 标签或者点击"搜索一下"跳转百度进行搜索时,利用事件冒泡原理,进行事件委托。这里没有考虑兼容性问题:

1 e = e || window.event; 2 target = e.target || e.srcElement;

6.除了点击事件,键盘事件–回车键以及上下键都是进行事件委托进行注册的。

最终能够实现键盘上下键鼠标选择,点击“搜索一下”或回车键实现跳转搜索。

代码: 1 DOCTYPE html> 2 3 4 5 6 7 8 9 10 search you want 11 12 html { 13 height: 100%; 14 } 15 16 body { 17 background: #f0f3ef; 18 height: 100%; 19 } 20 21 .container { 22 height: 100%; 23 display: flex; 24 justify-content: center; 25 align-items: center; 26 flex-direction: column; 27 } 28 29 .bgDiv { 30 box-sizing: border-box; 31 width: 595px; 32 height: 55px; 33 position: relative; 34 /* position: absolute; 35 left: 50%; 36 top: 50%; 37 transform: translate(-50%, -50%); */ 38 } 39 40 .search-input-text { 41 border: 1px solid #b6b6b6; 42 width: 495px; 43 background: #fff; 44 height: 33px; 45 line-height: 33px; 46 font-size: 18px; 47 padding: 3px 0 0 7px; 48 } 49 50 .search-input-button { 51 width: 90px; 52 height: 38px; 53 color: #fff; 54 font-size: 16px; 55 letter-spacing: 3px; 56 background: #3385ff; 57 border: .5px solid #2d78f4; 58 margin-left: -5px; 59 vertical-align: top; 60 opacity: .9; 61 } 62 63 .search-input-button:hover { 64 opacity: 1; 65 box-shadow: 0 1px 1px #333; 66 cursor: pointer; 67 } 68 69 .suggest { 70 width: 502px; 71 position: absolute; 72 top: 38px; 73 border: 1px solid #999; 74 background: #fff; 75 display: none; 76 } 77 78 .suggest ul { 79 list-style: none; 80 margin: 0; 81 padding: 0; 82 } 83 84 .suggest ul li { 85 padding: 3px; 86 font-size: 17px; 87 line-height: 25px; 88 cursor: pointer; 89 } 90 91 .suggest ul li:hover { 92 background-color: #e5e5e5 93 } 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 var suggestContainer = document.getElementsByClassName("suggest")[0]; 111 var searchInput = document.getElementsByClassName("search-input-text")[0]; 112 var bgDiv = document.getElementsByClassName("bgDiv")[0]; 113 var searchResult = document.getElementById("search-result"); 114 115 // 清除建议框内容 116 function clearContent() { 117 var size = searchResult.childNodes.length; 118 for (var i = size - 1; i >= 0; i--) { 119 searchResult.removeChild(searchResult.childNodes[i]); 120 } 121 }; 122 123 var timer = null; 124 // 注册输入框键盘抬起事件 125 searchInput.onkeyup = function (e) { 126 suggestContainer.style.display = "block"; 127 // 如果输入框内容为空 清除内容且无需跨域请求 128 if (this.value.length === 0) { 129 clearContent(); 130 return; 131 } 132 if (this.timer) { 133 clearTimeout(this.timer); 134 } 135 if (e.keyCode !== 40 && e.keyCode !== 38) { 136 // 函数节流优化 137 this.timer = setTimeout(() => { 138 // 创建script标签JSONP跨域 139 var script = document.createElement("script"); 140 script.src = "https://www.baidu.com/su?&wd=" + encodeURI(this.value.trim()) + 141 "&p=3&cb=handleSuggestion"; 142 document.body.appendChild(script); 143 }, 130) 144 } 145 146 }; 147 148 // 回调函数处理返回值 149 function handleSuggestion(res) { 150 // 清空之前的数据!! 151 clearContent(); 152 var result = res.s; 153 // 截取前五个搜索建议项 154 if (result.length > 4) { 155 result = result.slice(0, 5) 156 } 157 for (let i = 0; i = size) { 205 i = 0; 206 } 207 if (i clearContent() 229 230 231 232

 

 

转载自:http://www.pianshen.com/article/564159407/



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3