一.节点
1.概述
(1)概念
网页中的所有内容都是节点(标签,属性,文本,注释等),一般的节点至少要拥有nodeType(类型),nodeName(节点名称)和nodeValue(节点值)这三个基本属性。
(2)分类
元素节点 nodeType 为1
属性节点 nodeType 为2
文本节点 nodeType 为3(包含,文字,空格,换行等)
(3)层级关系
分为父兄子层级
2.获取节点
(1)获取父级节点
element.parentNode
//得到的是离元素最近的父级节点,如果找不到父节点就返回为 null。
demo
<body>
<div class="demo">
<div class="box">
<span class="erweima">×</span>
</div>
</div>
<script>
//1.用获取元素的方法
// var box = document.querySelector('.box');
// 2.用获取父级节点的方法
//先获取子节点,在根据子节点获取父级节点
var erweima = document.querySelector('.erweima');
console.log(erweima.parentNode); //输出 <div class="box"></div>
</script>
</body>
(2)获取子节点
方法一
element.childNodes
//返回所有的子节点包含元素节点,文本节点等
demo
<body>
<!-- 节点的优点 -->
<div>我是div</div>
<span>我是span</span>
<ul>
<li>我是li</li>
<li>我是li</li>
<li>我是li</li>
<li>我是li</li>
</ul>
<script>
var ul = document.querySelector('ul');
// 方法一:用获取元素的方法获取(只能获取li)
var lis = ul.querySelectorAll('li');
console.log(lis[0].nodeType) //第一个节点为元素节点(li),所以输出1
// 方法二: 用获取节点的方法获取(所有的子节点 包含 元素节点 文本节点等)
console.log(ul.childNodes[0].nodeType); //第一个节点为文本节点(空格),所以输出3
</script>
</body>
方法二
element.children
获取所有的子元素节点
demo
<body>
<div>我是div</div>
<span>我是span</span>
<ul>
<li>我是li</li>
<li>我是li</li>
<li>我是li</li>
<li>我是li</li>
</ul>
<script>
var ul = document.querySelector('ul');
//children 获取所有的子元素节点
console.log(ul.children[0].nodeType); //输出1
</script>
</body>
(3)返回第一个和最后一个子节点
方法一
element.firstChild 和 element.lastChild
//返回第一个和最后一个子节点,不管是文本节点还是元素节点
demo
<body>
<ol>
<li>我是li1</li>
<li>我是li2</li>
<li>我是li3</li>
<li>我是li4</li>
<li>我是li5</li>
</ol>
<script>
var ol = document.querySelector('ol');
console.log(ol.firstChild.nodeType); //输出第一个节点,为文本节点(空格)
console.log(ol.lastChild.nodeType);//输出第一个节点,为文本节点(空格)
</script>
</body>
方法二
element.firstElementChild 和 element.lastElementChild// 返回第一个和最后一个子元素节点 ie9才支持
demo
<body> <ol> <li>我是li1</li> <li>我是li2</li> <li>我是li3</li> <li>我是li4</li> <li>我是li5</li> </ol> <script> var ol = document.querySelector('ol'); // 2. firstElementChild 返回第一个子元素节点 ie9才支持 console.log(ol.firstElementChild); console.log(ol.lastElementChild); // 3. 实际开发的写法 既没有兼容性问题又返回第一个子元素 console.log(ol.children[0]); console.log(ol.children[ol.children.length - 1]); </script></body>
方法三 —— 兼容写法
<body> <ol> <li>我是li1</li> <li>我是li2</li> <li>我是li3</li> <li>我是li4</li> <li>我是li5</li> </ol> <script> var ol = document.querySelector('ol'); // 既没有兼容性问题又返回第一个和最后一个子元素 console.log(ol.children[0]); console.log(ol.children[ol.children.length - 1]); </script></body>
综合demo——下拉菜单
<head> <!-- 样式部分 --> <style> * { margin: 0; padding: 0; } li { list-style-type: none; } a { text-decoration: none; font-size: 14px; } .nav { margin: 100px; } .nav>li { position: relative; float: left; 80px; height: 41px; text-align: center; } .nav li a { display: block; 100%; height: 100%; line-height: 41px; color: #333; } .nav>li>a:hover { background-color: #eee; } .nav ul { display: none; position: absolute; top: 41px; left: 0; 100%; border-left: 1px solid #FECC5B; border-right: 1px solid #FECC5B; } .nav ul li { border-bottom: 1px solid #FECC5B; } .nav ul li a:hover { background-color: #FFF5DA; } </style></head><body> <!-- 结构部分 --> <ul class="nav"> <li> <a href="#">微博1</a> <ul> <li> <a href="">私信</a> </li> <li> <a href="">评论</a> </li> <li> <a href="">@我</a> </li> </ul> </li> <li> <a href="#">微博2</a> <ul> <li> <a href="">私信</a> </li> <li> <a href="">评论</a> </li> <li> <a href="">@我</a> </li> </ul> </li> </ul> <!-- js部分 --> <script> // 1. 获取元素 var nav = document.querySelector('.nav'); var lis = nav.children; // 得到4个小li // 2.循环注册事件 for (var i = 0; i < lis.length; i++) { lis[i].onmouseover = function() { this.children[1].style.display = 'block'; } lis[i].onmouseout = function() { this.children[1].style.display = 'none'; } } </script></body>
(4)获取兄弟节点
方法一
element.nextSibling//获取下一个兄弟节点,包含元素节点或者文本节点等等
方法二
element.previousSibling//获取上一个兄弟节点 包含元素节点或者文本节点等
demo
<body> <div>我是div</div> <span>我是span</span> <script> var div = document.querySelector('div'); console.log(div.nextSibling); //输出下一个兄弟节点(空格) console.log(div.previousSibling); //输出上一个兄弟节点(空格) </script></body>
方法三
element. nextElementSibling// 得到下一个兄弟元素节点
方法四
element.previousElementSibling//得到上一个兄弟元素节点
demo
<body> <div>我是div</div> <span>我是span</span> <script> var div = document.querySelector('div'); console.log(div.nextElementSibling); //输出下一个兄弟元素节点(span元素) console.log(div.previousElementSibling); //输出上一个兄弟节点(没有上一个兄弟节点,输出nul) </script></body>
3.创建和插入节点
(1)创建节点元素节点
document.createElement('元素名');
demo
var li = document.createElement('li');
注:
创建之后需要插入或者说是添加到其他地方,否则创建的元素就没有任何意义。
(2)插入节点
将一个节点添加到指定父节点的子节点末尾。类似于css的after伪元素。
node.appendChild(achild)// node :是父级 //child :是要添加的元素
将一个节点添加到父级节点的子节点前面,类似于css的before。
node.insertBefore(child, 指定元素)//node: 父级元素//child: 是要插入的节点//指定元素:是在某个元素前面插入
demo
<body> <ul> <li>123</li> </ul> <script> // 创建元素节点 var li1 = document.createElement('li'); // 获取父级节点 var ul = document.querySelector('ul'); // 添加节点 node.appendChild(child) ul.appendChild(li1); // 添加节点 node.insertBefore(child, 指定元素); var li2 = document.createElement('li'); ul.insertBefore(li2, ul.children[0]); </script></body>
demo——简化版留言板
<!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"> <title>Document</title> <style> * { margin: 0; padding: 0; } body { padding: 100px; } textarea { 200px; height: 100px; border: 1px solid pink; outline: none; resize: none; } ul { margin-top: 50px; } li { 300px; padding: 5px; background-color: rgb(245, 209, 243); color: red; font-size: 14px; margin: 15px 0; } </style> </head> <body> <textarea name="" id=""></textarea> <button>发布</button> <ul> </ul> <script> // 1. 获取元素 var btn = document.querySelector('button'); var text = document.querySelector('textarea'); var ul = document.querySelector('ul'); // 2. 注册事件 btn.onclick = function() { if (text.value == '') { alert('您没有输入内容'); return false; } else { // console.log(text.value); // (1) 创建元素 var li = document.createElement('li'); // 给li赋值 li.innerHTML = text.value; // (2) 添加元素 ul.insertBefore(li, ul.children[0]); } } </script> </body></html>
4.删除节点
删除父级节点里面的某一个子节点
node.removeChild(child)
//node :父级节点
//child : 指定删除的节点
demo
<body>
<button>删除</button>
<ul>
<li>熊大</li>
<li>熊二</li>
<li>光头强</li>
</ul>
<script>
//获取元素
var ul = document.querySelector('ul');
var btn = document.querySelector('button');
// 点击按钮依次删除里面的ul里面的子节点li
btn.onclick = function() {
//如果父级节点没有子节点了,那么就禁用删除按钮
if (ul.children.length == 0) {
this.disabled = true;
} else {
ul.removeChild(ul.children[0]);
}
}
</script>
</body>
5.复制节点
node.cloneNode()
//node: 是要复制的节点
括号为空或者里面是false 浅拷贝 只复制标签不复制里面的内容
node.cloneNode(true)
括号为true 深拷贝 复制标签复制里面的内容
demo
<body>
<ul>
<li>1111</li>
<li>2</li>
<li>3</li>
</ul>
<script>
var ul = document.querySelector('ul');
var lili = ul.children[0].cloneNode(true); //复制ul里面的第一个子元素
ul.appendChild(lili); //在ul里最后一个li后面添加复制的li
</script>
</body>
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">
<title>Document</title>
<style>
table {
500px;
margin: 100px auto;
border-collapse: collapse;
text-align: center;
}
td,
th {
border: 1px solid #333;
}
thead tr {
height: 40px;
background-color: #ccc;
}
</style>
</head>
<body>
<table cellspacing="0">
<thead>
<tr>
<th>姓名</th>
<th>科目</th>
<th>成绩</th>
<th>操作</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<script>
// 1.先去准备好学生的数据
var datas = [{
name: '小一',
subject: 'JavaScript',
score: 100
}, {
name: '小二',
subject: 'JavaScript',
score: 98
}, {
name: '小三',
subject: 'JavaScript',
score: 99
}, {
name: '小四',
subject: 'JavaScript',
score: 88
}, {
name: '小五',
subject: 'JavaScript',
score: 0
}];
// 2. 往tbody 里面创建行: 有几个人就创建几行
var tbody = document.querySelector('tbody');
for (var i = 0; i < datas.length; i++) {
// 1. 创建 tr行
var tr = document.createElement('tr');
tbody.appendChild(tr);
// 2. 行里面创建单元格
for (var k in datas[i]) {
// 创建单元格
var td = document.createElement('td');
// 把对象里面的属性值 datas[i][k] 给 td
td.innerHTML = datas[i][k];
tr.appendChild(td);
}
// 3. 创建有删除2个字的单元格
var td = document.createElement('td');
td.innerHTML = '<a href="javascript:;">删除 </a>';
tr.appendChild(td);
}
// 4. 删除操作
var as = document.querySelectorAll('a');
for (var i = 0; i < as.length; i++) {
as[i].onclick = function() {
// 点击a 删除 当前a 所在的行
tbody.removeChild(this.parentNode.parentNode)
}
}
</script>
</body>
</html>
二.事件
1.注册事件
(1)传统事件
缺点:
具有唯一性,同一个事件只能设置一个处理函数,如果设置多个,后面的函数会覆盖前面的函数。
<body>
<button>传统注册事件</button>
<script>
var btns = document.querySelector('button');
btns.onclick = function() {
alert('hello word');
}
</script>
</body>
(2)方法监听事件
element.addEventListener(type, function, useCapture)
注:
type为事件类型,为字符串 ,比如’click‘,'mouseover'在这里不带on。
function,事件处理函数,同一个元素 同一个事件可以添加多个侦听器(事件处理程序)
useCapture,可选。值为布尔值(true和false),指定事件是否在捕获或冒泡阶段执行,默认为冒泡事件(false)
<body>
<button>方法监听注册事件</button>
<script>
var btns = document.querySelector('button')
btns.addEventListener('click', function() {
alert('方法监听事件1');
})
//同一个事件绑定多个事件函数,两个事件函数都能执行
btns.addEventListener('click', function() {
alert("方法监听事件2");
})
</script>
</body>
2.删除(解绑)事件
(1)传统删除事件
<body>
<div>1</div>
<script>
var div = document.querySelector('div');
div.onclick = function() {
alert(11);
div.onclick = null; //// 传统方式删除事件,弹出一次之后就不会在弹出
}
</script>
(2) 删除事件
element.removeEventListener('type',fun_name)
//type : 要删除的事件类型
//fun_name : 要删除的函数名
<body>
<div>1</div>
<script>
var div = document.querySelector('div');
//. removeEventListener 删除事件
div.addEventListener('click', fn) // 里面的fn 不需要调用加小括号
//定义函数
function fn() {
alert(22);
div.removeEventListener('click', fn);
}
</script>
</body>
3.DOM事件流
(1)概念
事件流描述的是从页面中接收事件的顺序。事件发生时会在元素之间按照特定的顺序传播,这个传播过程即为DOM事件流。
(2)阶段
1.捕获阶段
2.当前目标阶段
3.冒泡阶段
给一个div,注册事件
注:
1. JS 代码中<u>只能执行捕获,冒泡其中的一个阶段</u>。
2. onclick 和 attachEvent(ie) 只能得到冒泡阶段。
3. 捕获阶段 如果addEventListener 第三个参数是 true 那么则处于捕获阶段 document ——> html ——> body ——> father ——> son
<style>
.father {
overflow: hidden;
300px;
height: 300px;
margin: 100px auto;
background-color: pink;
text-align: center;
}
.son {
200px;
height: 200px;
margin: 50px;
background-color: purple;
line-height: 200px;
color: #fff;
}
</style>
<body>
<div class="father">
<div class="son">son盒子</div>
</div>
<script>
var son = document.querySelector('.son');
son.addEventListener('click', function() {
alert('son');
}, true); //设置为true
var father = document.querySelector('.father');
father.addEventListener('click', function() {
alert('father');
}, true);
</script>
</body>
- 冒泡阶段 如果addEventListener 第三个参数是 false 或者 省略 那么则处于冒泡阶段 son -> father ->body -> html -> document
<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">
<title>Document</title>
<style>
.father {
overflow: hidden;
300px;
height: 300px;
margin: 100px auto;
background-color: pink;
text-align: center;
}
.son {
200px;
height: 200px;
margin: 50px;
background-color: purple;
line-height: 200px;
color: #fff;
}
</style>
</head>
<body>
<div class="father">
<div class="son">son盒子</div>
</div>
<script>
var son = document.querySelector('.son');
son.addEventListener('click', function() {
alert('son');
}, false);
var fa = document.querySelector('.father')
fa.addEventListener('click', function() {
alert('father');
},false)
document.addEventListener('click', function() {
alert('document');
},false)
//先弹出son,在弹出father,最后弹出document
</script>
</body>
4.事件对象
(1)概念
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
div {
100px;
height: 100px;
background-color: pink;
}
</style>
</head>
<body>
<div>123</div>
<script>
// 事件对象
var div = document.querySelector('div');
div.onclick = function(event) {
console.log(event);
}
</script>
</body>
注:
- event 就是一个事件对象 写到我们侦听函数的 小括号里面 当形参来看
- 事件对象只有有了事件才会存在,它是系统给我们自动创建的,不需要我们传递参数
- 事件对象 是 我们事件的一系列相关数据的集合 跟事件相关的 比如鼠标点击里面就包含了鼠标的相关信息,比如鼠标坐标,如果是键盘事件里面就包含的键盘事件的信息 比如 判断用户按下了那个键
- 这个事件对象我们可以自己命名 比如 event 、 evt、 e
- 事件对象也有兼容性问题 ie678 通过 window.event 兼容性的写法 e = e || window.event;
(2)常见事件对象的属性和方法
属性方法 | 说明 |
---|---|
e.target | 返回触发事件的对象(标准) |
e.srcElement | 返回触发事件的对象(低版本浏览器使用) |
e.type | 返回事件的类型,比如click,mouseover等 |
e.cancelBubble | 该属性阻止冒泡(低版本浏览器使用) |
e.stopPropagation() | 阻止冒泡事件 |
e.returnValue | 该属性阻止默认事件(默认行为,比如跳转,低版本浏览器使用) |
e.prevenDefault() | 该属性阻止默认事件 |
e.target 和this的区别
-
e.target 返回的是触发事件的对象(元素)
-
this 返回的是绑定事件的对象(元素)
<body>
<ul>
<li>abc</li>
<li>abc</li>
<li>abc</li>
</ul>
<script>
var ul = document.querySelector('ul');
ul.addEventListener('click', function(e) {
// ul绑定了事件 那么this 就指向ul
console.log(this); //输出<ul>....<ul>
// e.target 指向我们点击的那个对象 我们点击的是li, e.target 指向的就是li
console.log(e.target); //输出<li>abc<li>
})
</script>
</body>
demo——阻止默认事件
<body>
<a href="http://www.baidu.com">百度</a>
<script>
// 阻止默认行为(事件) 让链接不跳转 或者让提交按钮不提交
var a = document.querySelector('a');
a.addEventListener('click', function(e) {
e.preventDefault(); // dom 标准写法
})
</script>
</body>
demo——返回事件的类型
<body>
<div>123</div>
<script>
var div = document.querySelector('div');
div.addEventListener('click', fn);
div.addEventListener('mouseover', fn);
div.addEventListener('mouseout', fn);
//1. 返回事件类型
function fn(e) {
console.log(e.type);
}
</script>
</body>
demo——阻止事件冒泡
<!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">
<title>Document</title>
</head>
<head>
<style>
.father {
overflow: hidden;
300px;
height: 300px;
margin: 100px auto;
background-color: pink;
text-align: center;
}
.son {
200px;
height: 200px;
margin: 50px;
background-color: purple;
line-height: 200px;
color: #fff;
}
</style>
</head>
<body>
<div class="father">
<div class="son">son儿子</div>
</div>
<script>
// 阻止冒泡 dom 推荐的标准 stopPropagation()
var son = document.querySelector('.son');
son.addEventListener('click', function (e) {
alert('son');
e.stopPropagation(); })// stop 停止 Propagation 传播
// //下面的不会弹出
var father = document.querySelector('.father');
father.addEventListener('click', function () {
alert('father');
});
document.addEventListener('click', function () {
alert('document');
})
</script>
</body>
</html>
(3)事件委托
事件委派也称为事件代理,在jquery里面称为事件委派。
原理
不给每个子节点单独设置事件监听器,而是将事件监听器设置在父级节点上,通过子节点来触发父级身上的监听器,达到把监听器设置在子节点上一样效果。
5.鼠标事件
(1)常见鼠标事件
事件 | 条件 |
---|---|
onclick | 鼠标左键触发 |
onmouseover | 鼠标经过触发 |
onmouseout | 鼠标离开 |
onfocus | 获取鼠标焦点触发 |
onblur | 鼠标失去焦点触发 |
onmousemove | 鼠标移动触发 |
onmouseup | 鼠标弹起触发 |
onmousedown | 鼠标按下触发 |
demo
<body>
我是一段不愿意分享的文字
<script>
// 1. contextmenu 我们可以禁用右键菜单
document.addEventListener('contextmenu', function(e) {
e.preventDefault();
})
// 2. 禁止选中文字 selectstart
document.addEventListener('selectstart', function(e) {
e.preventDefault();
})
</script>
</body>
(2)常见鼠标对象
鼠标事件对象 | 说明 |
---|---|
e.clientX | 返回鼠标相对于浏览器窗口可视区的X坐标 |
e.lientY | 返回鼠标相对于浏览器窗口可视区的Y坐标 |
e.pageX | 返回鼠标相对于文档页面的X坐标 |
e.pageY | 返回鼠标相对于文档页面的Y坐标 |
e.screenX | 返回鼠标相对于电脑屏幕的X坐标 |
e.screenY | 返回鼠标相对于电脑屏幕的Y坐标 |
demo
<body>
<script>
// 鼠标事件对象 MouseEvent
document.addEventListener('click', function(e) {
// 1. client 鼠标在可视区的x和y坐标
console.log(e.clientX);
console.log(e.clientY);
console.log('---------------------');
// 2. page 鼠标在页面文档的x和y坐标
console.log(e.pageX);
console.log(e.pageY);
console.log('---------------------');
// 3. screen 鼠标在电脑屏幕的x和y坐标
console.log(e.screenX);
console.log(e.screenY);
})
</script>
</body>
demo——跟随鼠标移动的图片
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
img {
position: absolute;
top: 2px;
}
</style>
</head>
<body>
<img src="images/angel.gif" alt="">
<script>
var pic = document.querySelector('img');
document.addEventListener('mousemove', function(e) {
// 1. mousemove只要我们鼠标移动1px 就会触发这个事件
// console.log(1);
// 2.核心原理: 每次鼠标移动,我们都会获得最新的鼠标坐标, 把这个x和y坐标做为图片的top和left 值就可以移动图片
var x = e.pageX;
var y = e.pageY;
console.log('x坐标是' + x, 'y坐标是' + y);
//3 . 千万不要忘记给left 和top 添加px 单位
pic.style.left = x - 50 + 'px';
pic.style.top = y - 40 + 'px';
});
</script>
</body>
6.键盘事件
(1)常见键盘事件
事件 | 触发条件 |
---|---|
onkeyup | 某个键盘按键被松开时触发 |
onkeydown | 某个键盘按键被按下时触发 |
nokeypress | 某个键盘按键被按下时触发,但是不识别功能键,比如,ctrl,shift,箭头等 |
demo
<script>
// keyup 按键弹起的时候触发
document.addEventListener('keyup', function() {
console.log('我弹起了');
})
//. keypress 按键按下的时候触发
document.addEventListener('keypress', function() {
console.log('我按下了press');
})
//2. keydown 按键按下的时候触发 能识别功能键 比如 ctrl shift 左右箭头啊
document.addEventListener('keydown', function() {
console.log('我按下了down');
})
// 三个事件的执行顺序 keydown -- keypress -- keyup
</script>
(2)键盘事件对象
事件对象 | 描述 |
---|---|
keycode | 返回按下的按键的ASCLL值 |
<body>
<script>
// 1. 我们的keyup 和keydown事件不区分字母大小写 a 和 A 得到的都是65
// 2. 我们的keypress 事件 区分字母大小写 a 97 和 A 得到的是65
document.addEventListener('keyup', function(e) {
console.log('up:' + e.keyCode);
// 我们可以利用keycode返回的ASCII码值来判断用户按下了那个键
if (e.keyCode === 65) {
alert('您按下的a键');
} else {
alert('您没有按下a键')
}
})
document.addEventListener('keypress', function(e) {
// console.log(e);
console.log('press:' + e.keyCode);
})
</script>
</body>
demo——仿京东快递查询
效果: 快递单号输入内容时, 在上面显示更大的字体,提高用户体验
<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"> <title>Document</title> <style> * { margin: 0; padding: 0; } .search { position: relative; 178px; margin: 100px; } .con { display: none; position: absolute; top: -40px; 171px; border: 1px solid rgba(0, 0, 0, .2); box-shadow: 0 2px 4px rgba(0, 0, 0, .2); padding: 5px 0; font-size: 18px; line-height: 20px; color: #333; } .con::before { content: ''; 0; height: 0; position: absolute; top: 28px; left: 18px; border: 8px solid #000; border-style: solid dashed dashed; border-color: #fff transparent transparent; } </style></head><body> <div class="search"> <div class="con">123</div> <input type="text" placeholder="请输入您的快递单号" class="jd"> </div> <script> // 快递单号输入内容时, 上面的大号字体盒子(con)显示(这里面的字号更大) // 表单检测用户输入: 给表单添加键盘事件 // 同时把快递单号里面的值(value)获取过来赋值给 con盒子(innerText)做为内容 // 如果快递单号里面内容为空,则隐藏大号字体盒子(con)盒子 var con = document.querySelector('.con'); var jd_input = document.querySelector('.jd'); jd_input.addEventListener('keyup', function() { // console.log('输入内容啦'); if (this.value == '') { con.style.display = 'none'; } else { con.style.display = 'block'; con.innerText = this.value; } }) // 当我们失去焦点,就隐藏这个con盒子 jd_input.addEventListener('blur', function() { con.style.display = 'none'; }) // 当我们获得焦点,就显示这个con盒子 jd_input.addEventListener('focus', function() { if (this.value !== '') { con.style.display = 'block'; } }) </script></body>