好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

JS实现百度搜索框

本文实例为大家分享了JS实现百度搜索框的具体代码,供大家参考,具体内容如下

实现原理

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

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

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

?

var script = document.createElement( "script" );

script.src =

  "https://www.baidu.com/su?&wd=" +

  encodeURI( this .value.trim()) +

  "&p=3&cb=handleSuggestion" ;

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 标签或者点击"搜索一下"跳转百度进行搜索时,利用事件冒泡原理,进行事件委托。 这里没有考虑兼容性问题:

?

e = e || window.event;

target = e.target || e.srcElement;

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

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

代码:

?

<!DOCTYPE html>

< html lang = "en" >

 

< head >

  < meta charset = "UTF-8" >

  < meta name = "viewport" content = "width=device-width, initial-scale=1.0" >

  <!-- 兼容性视图 -->

  < meta http-equiv = "X-UA-Compatible" content = "ie=edge" >

  < meta content = "更方便快捷搜索,从而达到事半功倍的效果" name = "description" >

  < title >search you want</ title >

  < style >

  html {

  height: 100%;

  }

 

  body {

  background: #f0f3ef;

  height: 100%;

  }

 

  .container {

  height: 100%;

  display: flex;

  justify-content: center;

  align-items: center;

  flex-direction: column;

  }

 

  .bgDiv {

  box-sizing: border-box;

  width: 595px;

  height: 55px;

  position: relative;

  /* position: absolute;

  left: 50%;

  top: 50%;

  transform: translate(-50%, -50%); */

  }

 

  .search-input-text {

  border: 1px solid #b6b6b6;

  width: 495px;

  background: #fff;

  height: 33px;

  line-height: 33px;

  font-size: 18px;

  padding: 3px 0 0 7px;

  }

 

  .search-input-button {

  width: 90px;

  height: 38px;

  color: #fff;

  font-size: 16px;

  letter-spacing: 3px;

  background: #3385ff;

  border: .5px solid #2d78f4;

  margin-left: -5px;

  vertical-align: top;

  opacity: .9;

  }

 

  .search-input-button:hover {

  opacity: 1;

  box-shadow: 0 1px 1px #333;

  cursor: pointer;

  }

 

  .suggest {

  width: 502px;

  position: absolute;

  top: 38px;

  border: 1px solid #999;

  background: #fff;

  display: none;

  }

 

  .suggest ul {

  list-style: none;

  margin: 0;

  padding: 0;

  }

 

  .suggest ul li {

  padding: 3px;

  font-size: 17px;

  line-height: 25px;

  cursor: pointer;

  }

 

  .suggest ul li:hover {

  background-color: #e5e5e5

  }

  </ style >

</ head >

 

< body >

  < div class = "container" >

  < div class = "bgDiv" >

  < input type = "text" class = "search-input-text" value = "" autofocus placeholder = "关键词" >

  < input type = "button" value = "搜索一下" class = "search-input-button" id = "btn" >

  < div class = "suggest" >

  < ul id = "search-result" >

  </ ul >

  </ div >

  </ div >

  </ div >

 

  < script >

  var suggestContainer = document.getElementsByClassName("suggest")[0];

  var searchInput = document.getElementsByClassName("search-input-text")[0];

  var bgDiv = document.getElementsByClassName("bgDiv")[0];

  var searchResult = document.getElementById("search-result");

 

  // 清除建议框内容

  function clearContent() {

  var size = searchResult.childNodes.length;

  for (var i = size - 1; i >= 0; i--) {

  searchResult.removeChild(searchResult.childNodes[i]);

  }

  };

 

  var timer = null;

  // 注册输入框键盘抬起事件

  searchInput.onkeyup = function (e) {

  suggestContainer.style.display = "block";

  // 如果输入框内容为空 清除内容且无需跨域请求

  if (this.value.length === 0) {

  clearContent();

  return;

  }

  if (this.timer) {

  clearTimeout(this.timer);

  }

  if (e.keyCode !== 40 && e.keyCode !== 38) {

  // 函数节流优化

  this.timer = setTimeout(() => {

  // 创建script标签JSONP跨域

  var script = document.createElement("script");

  script.src = "https://www.baidu.com/su?&wd=" + encodeURI(this.value.trim()) +

  "&p=3&cb=handleSuggestion";

  document.body.appendChild(script);

  }, 130)

  }

 

  };

 

  // 回调函数处理返回值

  function handleSuggestion(res) {

  // 清空之前的数据!!

  clearContent();

  var result = res.s;

  // 截取前五个搜索建议项

  if (result.length > 4) {

  result = result.slice(0, 5)

  }

  for (let i = 0; i < result.length ; i++) {

  // 动态创建li标签

  var liObj = document .createElement("li");

  liObj.innerHTML = result [i];

  searchResult.appendChild(liObj);

  }

  // 自执行匿名函数--删除用于跨域的script标签

  (function () {

  var s = document .querySelectorAll('script');

  for (var i = 1 , len = s .length; i < len; i++) {

  document.body.removeChild(s[i]);

  }

  })()

  }

 

 

  function jumpPage() {

  window.open(`https://www.baidu.com/s?word=${encodeURI(searchInput.value)}`);

  }

 

  // 事件委托 点击li标签或者点击搜索按钮跳转到百度搜索页面

  bgDiv.addEventListener("click", function (e) {

  if (e.target.nodeName.toLowerCase() === 'li') {

  var keywords = e.target.innerText;

  searchInput.value = keywords ;

  jumpPage();

  } else if (e.target.id === 'btn') {

  jumpPage();

  }

  }, false);

 

  var i = 0 ;

  var flag = 1 ;

 

  // 事件委托 监听键盘事件

  bgDiv.addEventListener("keydown", function (e) {

  var size = searchResult .childNodes.length;

  if (e.keyCode === 13) {

  jumpPage();

  };

  // 键盘向下事件

  if (e.keyCode === 40) {

  if (flag === 0) {

  i = i + 2;

  }

  flag = 1 ;

  e.preventDefault();

  if (i >= size) {

  i = 0;

  }

  if (i < size ) {

  searchInput.value = searchResult .childNodes[i++].innerText;

  }

  };

  // 键盘向上事件

  if (e.keyCode === 38) {

  if (flag === 1) {

  i = i - 2;

  }

  flag = 0 ;

  e.preventDefault();

  if (i < 0) {

  i = size - 1;

  }

  if (i > -1) {

  searchInput.value = searchResult.childNodes[i--].innerText;

  }

  };

  }, false);

 

  // 点击页面任何其他地方 搜索结果框消失

  document.onclick = () => clearContent()

  </ script >

</ body >

 

</ html >

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/rujin_shi/article/details/83657566

查看更多关于JS实现百度搜索框的详细内容...

  阅读:40次