在日常生活中我们通过百度搜索相关内容时,会发现如下这样一个很有趣的现象:
那么对于这一部分具体是怎么实现的呢?
那么接下来我们就来实现一个和它差不多的效果把
这里主要就用到了表单事件里的 获焦事件(onfocus)、失焦事件(onblur)、以及文本框内容发生改变时的事件(oninput )
第一步我们要做的就是先有一个输入框,并且还需要有一个 ul 列表框用来盛放当我们在输入框里输入值时的一些智能提示内容,只不过在最开始的时候我们需要将 ul 列表框隐藏起来,大致如下所示:
* {
margin: 0px;
padding: 0px;
}
.search {
height: 40px;
width: 400px;
font-size: 20px;
border: 2px solid lightgray;
border-radius: 8px;
outline: none;
padding: 0 10px;
margin-top: 100px;
margin-left: 100px;
box-sizing: border-box;
position: relative;
}
.line {
position: absolute;
left: 115px;
top: 140px;
width: 360px;
height: 1px;
background-color: lightgray;
display: none;
}
.list {
width: 400px;
border: 2px solid blue;
border-top: none;
border-radius: 8px;
list-style: none;
margin-left: 100px;
display: none;
box-sizing: border-box;
}
.list li {
height: 30px;
line-height: 30px;
padding-left: 10px;
color: #666;
}
.list li:hover {
background-color: lightgrey;
color: blue;
}
<input type="text" class="search" />
<div class="line"></div>
<ul class="list"></ul>
接下来要实现的就是当输入框获得焦点时实现更改输入框的颜色值
当输入框失去焦点时其下边框颜色变为 lightgray,下边框为 2px solid lightgray,边框圆角为 8px以及隐藏列表框和分割线
// 0. 手动创建list里面的数据
let data=["张三","张四","张五","张六","张器","张巴巴","张九九","张时","张十一","张十二","张三四十","张张好地方","张会发生","李以恶","李房管局","李四三个","李四二二杠","李四色鬼","李四多个","李手动","李四获焦","李四放到","李四发","李乣","人","李二分","李问题","李而已","李热映","李获焦得到","李二号","李违法","李微软","李太热","李色好吧","李昆明回家","李四撒","李兔鳄"];
// 1. 获取相关元素
let ul = document.querySelector(".list");
let search = document.querySelector(".search");
let line = document.querySelector(".line");
// 2. 输入框 的获焦和失焦事件
search.onfocus = function(){
// 当 输入框 获得焦点时其边框的颜色变为蓝色
this.style.borderColor = "blue";
}
search.onblur = function(){
/**
* 当 输入框失去焦点时:
* 其下边框颜色变为 lightgray
* 其下边框为 2px solid lightgray
* 其边框圆角为 8px
* 下面的列表框隐藏,分割线隐藏
*/
this.style.borderColor = "lightgray";
this.style.borderBottom = "2px solid lightgray";
this.style.borderRadius = "8px";
ul.style.display="none";
line.style.display = "none";
}
紧接着需要实现的也就是核心区域:
通过 oninput 去监听输入框里面内容的变化,也就是去判断输入框里面有没有输入内容,通过 .value 的方式去获取输入框里输入的内容
当输入框里有内容时此时需要去遍历定义的假数据,然后将假数据里匹配得上的数据显示到 ul 列表框里,因此需要通过 filter 去进行过滤,然后通过 startsWith 去筛选出符合条件的所有开头的数据,通过for循环遍历动态创建li去盛放筛选出符合条件的数据并放入到ul列表框里进行显示
当输入框里没有内容或者如输入框里输入的内容和假数据里的数据不符合时就隐藏ul列表以及分割线
// 3. 给输入框添加oninput事件----当文本框的内容发生改变时,触发该事件
search.oninput= function(){
// i. 当输入框的内容发生变化时,输入框的下边框为 none
this.style.borderBottom = "none";
// ii. 获取输入框中输入的值,从而根据值的变化,动态筛选data中的数据,并显示到list里面去
let value= this.value;
// iii. 在添加新的li之前,清空list里面之前追加的li;
ul.innerHTML="";
// iv. 如果input里面没有输入内容,list就不出现,该事件就不用触发,只有输入框里有值即输入了内容才会触发
if(value!=""){
/**
* v. 遍历data数组中的数据,通过输入框里输入的值即value,去data里筛选出满足条件的数据,然后将其显示出来
* 其中 v 代表 data 中的每一项
* artwith--筛选以该字符串(input的value)开头的所有数据
* value--输入框里输入的值
*/
let arr = data.filter(v => v.startsWith(value));
// vi.如果筛选到了数据即arr的长度大于0;此时将数据显示到list当中
if(arr.length > 0){
// 遍历筛选出的符合条件的数据,并动态创建 li ,将符合条件的数据放入到 li 中,最后将 li 加入到 ul 标签中
for(let i=0;i<arr.length;i++){
let li=document.createElement("li");
li.innerHTML=arr[i];
ul.appendChild(li);
}
/**
* 去掉输入框的下边框(在最开始输入框的内容发生变化时就已经去掉了)以及左下右下的圆角
* 将输入框的颜色改为蓝色
* 显示分割线
* 显示之前隐藏的 ul 框
* 设置 ul 框的左下右下圆角为 8px ,与输入框的圆角保持一致
*/
this.style.borderRadius="8px 8px 0px 0px";
this.style.borderColor = "blue";
line.style.display = "block";
ul.style.display="block";
ul.style.borderRadius="0px 0px 8px 8px";
}
}
/**
* vii. 输入框里未输入数据
* 显示输入框的下边框并设置其圆角
* 隐藏ul列表
*/
else{
this.style.border ="2px solid lightgray";
this.style.borderRadius="8px";
ul.style.display="none";
}
最后效果如下:
源码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
* {
margin: 0px;
padding: 0px;
}
.search {
height: 40px;
width: 400px;
font-size: 20px;
border: 2px solid lightgray;
border-radius: 8px;
outline: none;
padding: 0 10px;
margin-top: 100px;
margin-left: 100px;
box-sizing: border-box;
position: relative;
}
.line {
position: absolute;
left: 115px;
top: 140px;
width: 360px;
height: 1px;
background-color: lightgray;
display: none;
}
.list {
width: 400px;
border: 2px solid blue;
border-top: none;
border-radius: 8px;
list-style: none;
margin-left: 100px;
display: none;
box-sizing: border-box;
}
.list li {
height: 30px;
line-height: 30px;
padding-left: 10px;
color: #666;
}
.list li:hover {
background-color: lightgrey;
color: blue;
}
</style>
</head>
<body>
<input type="text" class="search" />
<div class="line"></div>
<ul class="list"></ul>
<script>
// 0. 手动创建list里面的数据
let data=["张三","张四","张五","张六","张器","张巴巴","张九九","张时","张十一","张十二","张三四十","张张好地方","张会发生","李以恶","李房管局","李四三个","李四二二杠","李四色鬼","李四多个","李手动","李四获焦","李四放到","李四发","李乣","人","李二分","李问题","李而已","李热映","李获焦得到","李二号","李违法","李微软","李太热","李色好吧","李昆明回家","李四撒","李兔鳄"];
// 1. 获取相关元素
let ul = document.querySelector(".list");
let search = document.querySelector(".search");
let line = document.querySelector(".line");
// 2. 输入框 的获焦和失焦事件
search.onfocus = function(){
// 当 输入框 获得焦点时其边框的颜色变为蓝色
this.style.borderColor = "blue";
}
search.onblur = function(){
/**
* 当 输入框失去焦点时:
* 其下边框颜色变为 lightgray
* 其下边框为 2px solid lightgray
* 其边框圆角为 8px
* 下面的列表框隐藏,分割线隐藏
*/
this.style.borderColor = "lightgray";
this.style.borderBottom = "2px solid lightgray";
this.style.borderRadius = "8px";
ul.style.display="none";
line.style.display = "none";
}
// 3. 给输入框添加oninput事件----当文本框的内容发生改变时,触发该事件
search.oninput= function(){
// i. 当输入框的内容发生变化时,输入框的下边框为 none
this.style.borderBottom = "none";
// ii. 获取输入框中输入的值,从而根据值的变化,动态筛选data中的数据,并显示到list里面去
let value= this.value;
// iii. 在添加新的li之前,清空list里面之前追加的li;
ul.innerHTML="";
// iv. 如果input里面没有输入内容,list就不出现,该事件就不用触发,只有输入框里有值即输入了内容才会触发
if(value!=""){
/**
* v. 遍历data数组中的数据,通过输入框里输入的值即value,去data里筛选出满足条件的数据,然后将其显示出来
* 其中 v 代表 data 中的每一项
* artwith--筛选以该字符串(input的value)开头的所有数据
* value--输入框里输入的值
*/
let arr = data.filter(v => v.startsWith(value));
// vi.如果筛选到了数据即arr的长度大于0;此时将数据显示到list当中
if(arr.length > 0){
// 遍历筛选出的符合条件的数据,并动态创建 li ,将符合条件的数据放入到 li 中,最后将 li 加入到 ul 标签中
for(let i=0;i<arr.length;i++){
let li=document.createElement("li");
li.innerHTML=arr[i];
ul.appendChild(li);
}
/**
* 去掉输入框的下边框(在最开始输入框的内容发生变化时就已经去掉了)以及左下右下的圆角
* 将输入框的颜色改为蓝色
* 显示分割线
* 显示之前隐藏的 ul 框
* 设置 ul 框的左下右下圆角为 8px ,与输入框的圆角保持一致
*/
this.style.borderRadius="8px 8px 0px 0px";
this.style.borderColor = "blue";
line.style.display = "block";
ul.style.display="block";
ul.style.borderRadius="0px 0px 8px 8px";
}
}
/**
* vii. 输入框里未输入数据
* 显示输入框的下边框并设置其圆角
* 隐藏ul列表
*/
else{
this.style.border ="2px solid lightgray";
this.style.borderRadius="8px";
ul.style.display="none";
}
}
</script>
</body>
</html>