仿百度搜索框
2017-08-03 本文已影响37人
icessun
百度搜索框
分析
-
输入框聚焦的时候,有内容显示ul,否者,ul隐藏
- 发起请求
- 根据获取的数据,拼接到li,ul中
-
当编辑内容的时候,如果有内容,ul显示,否者,隐藏
-
当点击列表的时候,自动搜索
-
点击其他的地方,ul隐藏
-
点击百度一下的时候,开始搜索
-
按键盘上下键的时候,内容框的内容同步改变,当按enter的时候,开始搜索
-
事件委托
- 委托的对象(容器)范围越大,则操作的余地越大
- 余地越大,那么冒泡的副作用也越大,要阻止冒泡
-
原生js有dom映射
-
表单:面向对象,运动库
-
尽量少用hover,可以使用js控制 ,for循环
html与css
百度搜索框布局分析:首先上面是一个百度的图片,下面是一个搜索框,输入文字,一遍输入,右边发送请求,获取的数据显示在输入框的下面;输入框和展示信息的ul是兄弟关系
<div id='wrap'>

<div class='boxInner'>
<input type="text" id="txt"/><button href="javascript:;" id="btn">百度一下</button>
<ul id='ul'>
// 这种形式进行拼接 li里面包含a表示可以点击
// <li><a href="javascript:;">icessun-node</a></li>
// <li><a href="javascript:;">icessun-webpack</a></li>
</ul>
</div>
</div>
<style>
*{
margin:0;
padding:0;
border:0;
outline: none;
list-style: none;
}
body,html{
height: 100%;
overflow: hidden; //去掉页面的滚动条:boyd里面overflow:hidden
}
a{
text-decoration: none;
}
img{
display: block;
width:400px;
margin:100px auto 20px;
}
.boxInner{
width: 700px;
height:40px;
margin:0 auto;
position: relative;
}
.boxInner input{
width:528px;
height:38px;
float: left;
border: 1px solid #cccccc;
font-size: 20px;
padding:0 10px;
}
.boxInner > button{
display: block;
float: left;
width:150px;
height:40px;
text-align: center;
line-height: 40px;
background: #3385ff;
color: white;
font-size: 20px;
}
.boxInner ul{
position: absolute;
left:1px;
top:40px;
box-shadow: 0 1px 3px #333;
width:698px;
display: none;
}
.boxInner ul li{
height: 35px;
line-height: 35px;
font-size: 20px;
}
.boxInner ul li a{
color: #333;
padding-left: 20px;
display: block;
}
.boxInner ul li a.active{
background: #eeeeee;
}
.boxInner ul li a:hover{
background: #eeeeee;
}
</style>
ajax+jsonp跨域请求
原生js代码
// 获取我们要操作的元素
var oWrap=document.getElementById('wrap');
var oTxt=document.getElementById('txt');
var oBtn=document.getElementById('btn');
var oUl=document.getElementById('ul');
var aA=oUl.getElementsByTagName('a');
var myData=null; // 获取的数据
var n=-1; // li表中的个数
var oldValue=null; // 上下键按下的时候,保存开始输入框的数据
// 第一步 :输入框聚焦(onfocus)的时候,如果输入框里面有内容,显示ul列表,编辑内容(键盘按下的时候onkeyup)的时候,也显示ul列表
oTxt.onfocus=oTxt.onkeyup=showUl;
function showUl(){
// 获取输入框的内容
var inputData=this.value;
if(inputData.length){
// 有内容,就要发送请求ajax+jsonp,获取数据
ajax({
// 请求接口地址
url:'https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su',
// 发送到后台的请求参数,就是输入框里面的数据
data:{wd:inputData},
type:'jsonp',//返回数据的类型
jsonp:'cb',// 返回数据函数的名字,默认是callback
success:function(data){
myData=data.s;
// 数据拼接,绑定到ul里面
var strLi='';
for(var i=0;i<myData.length;i++){
strLi+='<li><a href="javascript:;">'+myData[i]+'</a></li>';
}
// 插入到ul
oUl.innerHTML=strLi;
}
});
oUl.style.display='block';
}else{
oUl.style.display='none';
}
};
// 第二步 点击列表里面的项可以搜索,点击百度一下也可以搜索,点击其他地方隐藏ul列表,列表里面有多个li,在一个容器里面,当有多个子元素可以点击的时候,可以使用事件委托,委托到document,进行统一管理
document.body.onclick=function(e){
e=e||window.event; // 绑定事件
var target=e.target||e.srcElement; // 获取事件源
// 判断事件源 当判断的事件源不能是li
if(target.tagName.toLowerCase()=='a' && target.parentNode.tagName.toLowerCase()=='li'){
// 开始发起请求
search(target.innerHTML);
}
// 当单击百度一下的时候,也可以搜索
if(target.tagName.toLowerCase()=='button'){
search(oTxt.value);
}
// 当点击的是input的时候,事件会往上冒泡,会使得ul隐藏,要阻止冒泡
if(target.tagName.toLowerCase()==='input'){
e.stopPropagation ? e.stopPropagation() : e.cancelBubble=true;
return;
}
// 点击 ul隐藏
oUl.style.display='none'
}
function search(val){
// 开启新页面
window.open('https://www.baidu.com/s?wd='+val,'_self');
return;
}
// input键盘事件的处理,按上下键输入同步显示内容,按回车键,进行搜索
oTxt.onkeydown=function(e){
e=e||window.e;
if(e.keyCode==40){ // 下键
n++;
if(n>=aA.length){
n=-1;
}
changeBg();
}else if(e.keyCode==38){ // 上键
n--;
if(n<=-2){
n=aA.length-1;
}
changeBg();
}else if(e.keyCode==13){// 回车键
search(oTxt.value);
}
};
function changeBg(){
// 保存初始值 保存一次
if(!oldValue){
oldValue=oTxt.value;
}
// 解绑编辑事件,因为按了上下键
oTxt.onkeyup=null;
// 改变背景,先清除全部样式,然后给特定元素添加样式
for(var i=0;i<aA.length;i++){
aA[i].className=null;
}
if(n==-1){
oTxt.value=oldValue;
}else{
aA[n].className='active';
oTxt.value=aA[n].innerHTML;
}
}