【干货分享|建议收藏】2万字详解DOM

感激相遇 你好 我是阿ken

作者:请叫我阿ken
链接:请叫我阿ken主页链接
来源:CSDN
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

🌊🌈关于前言:

文章部分内容及图片出自网络,如有问题请与我本人联系(主页介绍中有公众号)
本博客暂适用于刚刚接触 JS以及好久不看想要复习的小伙伴。

🌊🌈关于内容:

JavaScript DOM下

文章目录

7.1_排他思想简介

7.1.1_排他思想简介

排他思想,简单理解就是排除掉其他的(包括自己),然后再给自己设置想要实现的效果。总而言之,排他思想的实现步骤就是所有元素全部清除与设置当前元素。
例如,在开发中,如果有同一组元素,我们想要某一个元素实现某种样式, 这就需要用到循环的排他思想算法来实现。

案例:演示排他操作,

(1) 编写 HTML 结构代码,示例代码如下。

<!doctype html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
	
		<button>按钮1</button>
		<button>按钮2</button>
		<button>按钮3</button>
		<button>按钮4</button>
		<button>按钮5</button>
		
	</body>
</html>

在这里插入图片描述

(2) 编写 JavaScript 代码,实现单击按钮,改变当前按钮背景色效果,示例代码如下,

		<script>
			
			// 获取所有按钮元素
			var btns = document.getElementsByTagName('button');
			
			// btns 得到的是类数组对象,使用btns[i]访问数组里的每一个元素
			for(var i = 0; i < btns.length; i++) {
				btns[i].onclick = function() {
					// (1) 先把所有的按钮背景颜色去掉
					for(var i = 0; i < btns.length; i++) {
						btns[i].style.backgroundColor = '';
					}
					
					// (2)然后设置当前的元素背景颜色
					this.style.backgroundColor = 'pink';
				}
			}
			
		</script>

在这里插入图片描述
当你点击一个按钮时
在这里插入图片描述
在这里插入图片描述

上述代码中,获取所有按钮元素,存储在 btns 伪数组中。
使用 for 循环遍历伪数组中的每一个元素 btns[i] 。
给每一个元素添加单击事件。
利用 for 循环首先把所有的按钮背景颜色去掉,然后给当前的元素设置背景颜色为 pink 。

7.1.2_[ 案例 ] 鼠标指针经过时背景变色

当表格中的单元格比较多时,可以在用户鼠标指针经过时把当前行添加背景色,使表格内容显得清晰和一目了然,容易阅读。

(1) 编写 HTML 页面,示例代码如下。

<body>
<table>
<thead>
<tr>
<th>代码</th>
<th>名称</th>
<th>最新公布净值</th>
<th>累计净值</th>
<th>前单位净值</th>
<th>净值增长率</th>
</tr>
</thead>
<tbody>
<tr>
<td>0035**</td>
<td>3个月定期开放债券</td>
<td>1.075</td>
<td>1.079</td>
<td>1.074</td>
<td>+0.047%</td>
</tr>
... (此处省略多个tr)
</tbody>
</table>
</body>

(2) 实现鼠标指针经过时背景变色的效果,具体代码如下。

<script>
// 1.获取元素
var trs document.querySelector('tbody').querySelectorAll('tr'); 
// 2.利用循环绑定注册事件
for(var i = 0; i < trs.length; i++) {
// 3.鼠标指针经过事件 onmouseover
trs[i].onmouseover = function() {
this.className = 'bg';
};
// 4.鼠标指针离开事件onmouseout
trs[1].onmouseout = function() {
this.className = '';
};
}
</script>

上述代码中,第 3 行代码把获取到的 tbody 里面所有的行保存在变量 trs 中。第 5 行代码利用 for 循环来为 trs 中的每一个元素绑定事件。 第 7 ~ 9 行代码为 trs 中的每个元素绑定 onmouseover 鼠标指针经过事件,当鼠标指针进人的时候给当前 tr 项的类名设置为 bg 。第 11 ~ 13 行代码给 trs[i] 绑定 onmouseout 鼠标指针离开事件,当鼠标指针离开时给当前 tr 项的类名设置为空,去掉当前的背景颜色。

7.2_属性操作

在 HTML 中,元素有一些自带的属性,如 div 元素的属性有 id、class、title、style 。开发者也可以为元素添加自定义属性。在实际开发中,自定义属性有很广泛的应用,例如:保存一些需要在 JavaScript 中用到的数据。

7.2.1_获取属性值 element.属性

在 DOM 对象中可以使用 " element.属性 " 的方式来来获取内置的属性值,但是 DOM 对象并不能直接使用点语法获取到自定义属性的值,那么如何获取收自定义属性值呢?在 DOM 中,可以使用 getAttribute(‘属性’)方法来返回指定元素的属性值。

案例:演示如何获取属性值,

<!doctype html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		
		<div id="demo" index="1" class="nav"></div>
		
		<script>
			
			var div = document.querySelector('div');
			console.log(div.id); // 结果为:demo
			console.log(div.getAttribute('id')); // 结果为:demo
			console.log(div.getAttribute('index')); // 结果为:1
			
		</script>
		
	</body>
</html>

在这里插入图片描述

上述代码中,分别使用 element.属性 和 element.getAttribute 两种方式获取 div 元素的内置属性 id ,输出结果为 demo 。虽然以上两种方式都可以获取内置属性值,但是在实际运用中推荐使用 ” element. 属性 “ 这种较为简洁的方式。
使用 getAttribute(‘index’) 方式来获取开发者自定义的 index 属性,输出结果为 1 。

7.2.2_设置属性值 element.setAttribute(‘属性’,’ 值’)

在 DOM 对象中可以使用 " element.属性 = ‘值’ " 的方式设置内置的属性值,并且针对于自定义属性,提供了 " element.setAttribute(‘属性’,’ 值’) " 的方式进行设置。
值得一提的是,设置了自定义属性的标签,在浏览器中的 HTML 结构中可以看到该属性。

案例:演示如何设置属性值,

<!doctype html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		
		<div></div>
		
		<script>
			
			var div = document.querySelector('div');
			div.id = 'test';
			div.className = 'navs';
			div.setAttribute('index', 2);
			
		</script>
		
	</body>
</html>

上述代码中,使用 " element.属性 = ‘值’ " 的方式设置 div 元素内置属性,设置 id 值为 test , class 类名为 navs 。
使用 setAttribute() 方法,设置属性名为 index ,值为2。

另外,如果想要使用 setAttribute() 方式设置元素的类名,则可以添加以下代码。

div.setAttribute ('class', 'footer');

因为 class 比较特殊,在这里使用的属性值为 class , 值为 footer。

7.2.3_移除属性 element.removeAttribute( 属性)

掌握了元素属性的获取和设置之后,还有一个要学习的操作,就是元素属性的移除。
在DOM中使用 " element.removeAttribute( 属性) " 的方式来移除元素属性。

案例:演示如何移除属性值,

<!doctype html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		
		<div id="test" class="footer" index="2"></div>
		
		<script>
			
			var div = document.querySelector('div');
			div.removeAttribute('id');
			div.removeAttribute('class');
			div.removeAttribute('index');
			
		</script>
		
	</body>
</html>

上述代码中,使用 removeAttribute() 方法移除 div 元素的id、class、index 属性。

7.2.4_[ 案例 ] Tab栏切换

标签栏在网站中的使用非常普遍,它的优势在于可以在有限的空间内展示多块的内容,用户可以通过标签在多个内容块之间进行切换。

接下来我们使用自定义属性相关知识实现 Tab 栏切换效果。

(1) 编写 HTML 页面,示例代码如下,

<div class="tab">
<div class="tab_list">
<ul>
<li class="current">商品介绍</li>
<li>规格与包装</li>
<li>售后保障</li>
<li>商品评价(50000)</li>
<li>手机社区</li>
</u1>
</div>
<div class="tab_con">
<div class="item" style=" display: block; ">商品介绍模块内容</div>
<div class="item">规格与包装模块内容</div>
<div class="item">售后保障模块内容</div>
<div class="item">商品评价(50000)模块内容</div>
<div class="item">手机社区模块内容</div>
</div>
</div>

上述代码中,class 为 tab 的元素用于实现标签栏的外边框。第 2 ~ 10 行和第 11 ~ 17 行代码分别实现标签栏的标签部分和内容部分。其中,标签部分第 1 个 li 添加了 current 样式,用于实现当前标签的选中效果。同样的,将该标签下对应的内容块 div 也添加了 display: block 样式,用于显示当前标签下的内容,隐藏其他标签下的内容。

(2) 实现标签栏切换,具体代码如下。

<script>
// 获取标签部分的所有元素对象
var tab_list = document.querySelector (' .tab_llst ');
var lis = tab_list.guerySelectorAll('li');
// 获取内容部分的所有内容对象
var items = document.querySelectorAll ('.item');
for (var i = 0;i < lis.length; i++) {  // for循环绑定点击事件
lis[i].setAttribute ('index',i);
lis[i].className = function() {
for (var i = 0; i < lis.length; i++) {
lis[i].className = '';
}
this.className = 'current';
// 下面的显示内容模块
var index = this.getAttribute('index');
for (var i = 0; i < items.length; i++) {
items[i].style.display = 'none';
}
items[index].style.display = 'block';
};
}
</script>

上述代码中,第 3、4 行通过 querySeletorAIl() 方法获取元素。第 7 ~ 21 行代码用于遍历标签部分的每个元素对象 lis[i] ,并绑定单击事件。在事件处理函数中, 第 10 ~ 12 行代码利用排他思想实现单击当前项,清除所有 li 的 class 类,并且在第 13 行给自己设置 current 类。同时当事件发生时执行第 15 ~ 19 行代码,显示当前鼠标单击的标签及其对应的内容,隐藏其他标签的显示。

7.3_自定义属性

**一般的自定义属性可以通过 getAttribute (‘属性’) 方法来获取,但是有些自定义属性很容引起歧义,不容易判断是元素的自带属性还是自定义属性。**因此,HTML5 新增了自定义属性的规范。在 HTML5 中规定通过 " data-属性名 " 的方式设置自定义属性。

接下来我们将对自定义属性的操作进行详细讲解。

7.3.1_设置属性值

元素的 " data- " 自定义属性有两种设置方式,*

1. 在 HTML 中设置自定义属性 data-index

_
在 div 元素上设置 data-index 属性,示例代码如下。

<div data-index="2"></div>

上述代码中,data-index 就是一种自定义属性," data- " 是自定义属性的前缀,index 是开发者自定义的属性名。

2. 在 JavaScript 中设置自定义属性 (setAttribute、元素对象.dataset.属性名)

_
在 JavaScript 代码中,可以通过 setAttribute(‘属性’,值) 或者 " 元素对象.dataset.属性名 = ‘值’ " 两种方式设置自定义属性。需要注意的是,通过后者的方式只能设置以 " data-" 开头的自定义属性。
示例代码如下。

<!doctype html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		
		<div></div>
		
		<script>
			
			var div = document.querySelector('div');
			div.dataset.index = '2';
			div.setAttribute('data-name', 'andy');
			
		</script>
		
	</body>
</html>

上述代码中,通过 " 元素对象.dataset.属性名 " 的方式为 div 元素添加属性。
通过 setAttribute (‘属性’, ‘值’) 的方式添加 data-name = ‘andy’。

执行上述代码,在浏览器中查看 div 元素,结果如下所示。

<div data-index="2" data-name="andy"></div>

在这里插入图片描述

7.3.2_获取属性值

在 DOM 操作中,提供了两种获取属性值的方式,

1. 通过 getAttribute()

该方式可以获取内置属性或者自定义属性;

2. 使用 HTML5 新增的 " element.dataset.属性 " 或者 " element.dataset [’ 属性 '] " 。

_
推建使用第 1 种,因为第 2 种有兼容性问题,从 IE11 才开始支持。

案例:演示如何获取属性值,示例代码如下。

<!doctype html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
		
		<div getTime="20" data-index="2" data-list-name="andy"></div>
		
		<script>
			
			var div = document.querySelector('div');
			console.log(div.getAttribute('data-index')); // 结果为:2
			
			console.log(div.getAttribute('data-list-name')); // 结果为:andy
			
			// H5新增的获取自定义属性的方法,只能获取 data- 开头的属性
			console.log(div.dataset); // DOMStringMap {index: "2", listName: "andy"}
			
			console.log(div.dataset.index); // 结果为:2
			
			console.log(div.dataset['index']); // 结果为:2
			
			console.log(div.dataset.listName); // 结果为:andy
			
			console.log(div.dataset['listName']); //结果为:andy
			
		</script>
		
	</body>
</html>

在这里插入图片描述

上述代码中,代码中的 dataset 是一个集合, 里面存放了所有以 data 开头的自定义属性。如果自定义属性里面包含有多个连字符(-)时,获取的时候采取驼峰命名法,例如,上述行中的listName。

7.4_节点基础

仔细了解一下什么是节点

HTML 文档可以看作是一个节点树, 网页中的所有内容都是节点(包括元素、属性、文本、注释等)。

7.4.1_什么是节点

HTML DOM 树中的所有节点均可通过 JavaScript 进行访问,因此,可以利用操作节点的方式操作 HTML 中的元素。

一般来说,节点至少拥有 nodeType 节点类型)、nodeName ( 节点名称 ) 和 nodeValue ( 节点值 ) 这 3 个基本属性。

  • 元素节点,nodeType 为 1。

  • 属性节点,nodeType 为 2。

  • 文本节点,nodeType 为 3。文本节点包含文字、空格、换行等。

在实际开发中,节点操作主要操作的是元素节点,开发者可以根据 nodeType 的值来判断是否为元素节点。

7.4.2_节点层级

DOM 中将 HTML 文档视为树结构,一个 HTML 文件可以看作是所有元素组成的一个节点树,各元素节点之间有级别的划分。
具体示例如下。

<!DOCTYPE HTML>
<html>
	<head>
		<meta charset="UTF-8">
		<title>测试</title>
	</head>
	<body>
		
		<a href="#">链接</a>
		<p>段落...</p>
		
	</body>
</html>

在这里插入图片描述

在上述代码中,DOM 根据 HTML 中各节点的不同作用,可将其分别划分为标签节点、文本节点和属性节点。其中,标签节点也被称为元素节点。HTML 文档中的注释则单独叫作注释节点。

节点之间的层级关系,最常见的是父子兄弟层级关系。下面我们以 < head> 、< body> 与 < html> 节点为例进行介绍,具体如下。

  • 根节点: < html> 标签是整个文档的根节点,有且仅有一个。

  • 父节点: 指的是某一个节点的上级节点,例如,< html> 元素则是 < head> 和 < body> 的父节点。

  • 子节点: 指的是某一个节点的下级节点,例如,< head> 和 < body> 节点是 < html> 节点的子节点。

  • 兄弟节点: 两个节点同属于一个父节点,例如,< head> 和 < body> 互为兄弟节点。

在讲解了各种节点的层次关系后,接下来我们针对各层级节点的获取进行详细讲解。

1. 获取父级节点 obj.parentNode

_
在 JavaScript 中,可以使用 parentNode 属性来获得离当前元素的最近的一个父节点,如果找不到父节点就返回为 null,语法格式为: obj.parentNode。其中, obj 是一个 DOM 对象是通过获取元素的方法来获取的元素,如 getElementById() 方法等。

案例:演示如何获取当前元素的父节点,

<!DOCTYPE HTML>
<html>
	<head>
		<meta charset="UTF-8">
		<title>测试</title>
	</head>
	<body>
		
		<div class="demo">
			<div class="box">
				<span class="child">span元素</span>
			</div>
		</div>
		
		<script>
			
			var child = document.querySelector('.child');
			console.log(child.parentNode);
			
		</script>
		
	</body>
</html>

在这里插入图片描述

在这里插入图片描述

上述代码中,通过 querySelector() 获取类名为 child 的 span 元素,存储到 child 对象中。
在控制台输出离 child 元素最近的父级节点 ( box )。

2. 获取子级节点

不是很理解下述案例

_
在 JavaScript 中,可以使用 childNodes 属性或者 children 属性两种方式来获得当前元素的所有子节点的集合。

( 1 ) childNodes 属性

childNodes 属性获得的是当前元素的所有子节点的集合,该集合为即时更新的集合。

案例:演示如何获取当前元素子节点,

<!DOCTYPE HTML>
<html>
	<head>
		<meta charset="UTF-8">
		<title>测试</title>
	</head>
	<body>
		
		<ul>
			<li>我是li</li>
			<li>我是li</li>
			<li>我是li</li>
			<li>我是li</li>
		</ul>
		
		<script>
			
			// DOM 提供的方法(API)获取
			var ul = document.querySelector('ul');
			var lis = ul.querySelector('li');
			
			console.log(lis);
			console.log(ul.childNodes);
			console.log(ul.childNodes[0].nodeType);
			console.log(ul.childNodes[1].nodeType);
			
		</script>
		
	</body>
</html>

在这里插入图片描述

上述代码中,定义了一个无序列表 ul 。
测试 DOM 提供的 API 方法是否能够获取全部 li 元素。
使用节点的方式获取 ul 下的所有的子节点 ( 包括文本节点和元素节点 )。
根据 nodeType 属性来获取文本节点和元素节点的节点类型。

运行后发现 childNodes 属性返回的是 NodeList 对象的集合。返回值里面包含了元素节点、文本节点等其他类型的节点。

如果想要获取childNodes 里面的元素节点,需要做专门的处理。在上述代码中编写如下代码获取元素节点。

			for(var i = 0; i < ul.childNodes.length; i++) {
				if(ul.childNodes[i].nodeType === 1) {
					console.log(ul.childNodes[i]);
				}
			}

在这里插入图片描述

上述代码中,ul.childNodes[i] 是元素节点。

需要注意的是,childNodes 属性在 IE 6 ~ IE 8中不会获取文本节点,在 IE 9 及以上版本和主流浏览器中则可以获取文本节点。所以在实际开发中一般不提倡使用 childNodes。

( 2 ) children 属性

children 是一个可读的属性, 返回所有子元素节点。children 只返回子元素节点,其余节点不返回。目前各大浏览器都支持该属性,在实际开发中推荐使用 children。

案例:演示如何获取当前元素子节点,

<!DOCTYPE HTML>
<html>
	<head>
		<meta charset="UTF-8">
		<title>测试</title>
	</head>
	<body>
		
		<ol>
			<li>我是li1</li>
			<li>我是li2</li>
			<li>我是li3</li>
			<li>我是li4</li>
		</ol>
		
		<script>
			
			var ul = document.querySelector('ol');
			var lis = ul.querySelectorAll('li');
			console.log(ul.children);
			
		</script>
		
	</body>
</html>

在这里插入图片描述

上述代码中,通过 ul.children 属性获取 ul 元素的子元素,在控制台中的输出结果为 HTMLCollection(4) [li, li, li, li] 。

  • 小提示:
    _
    childNodes 属性与 children 属性虽然都可以以获取某元素的子元素,但是两者之间有一定的区别。前者用于节点操作,返回值是 NodeList 对象集合;后者用于元素操作,返回的是 HTMLCollection 对象集合。
( 3 ) 获取子节点 firstChild 属性和 lastChild 属性

firstChild 属性和 lastChild 属性,前者返回第一个子节点,后者返回的是最后一个子节点,如果找不到则返回 null。需要注意的是,它们的返回值包括文本节点和元素节点等。

( 4 ) 获取子元素节点 firstElementChild 属性和 lastElementChild 属性

firstElementChild 属性和 lastElementChild 属性,前者返回第一个子元素节点,后者返回最后一个子元素节点,如果找不到则返回 null。

需要注意的是,这两个属性有兼容性问题,IE9 以上才支持。

实际开发中,firstChild 和 lastChild 包含其他节点,操作不方便;而 firstElementChild 和 lastElementChild 又有兼容性问题,那么如何获取第一个子元素节点或最后一个子元素节点呢?
为了解决兼容性问题,在实际开发中通常使用 “ obj.children [ 索引 ] ” 的方式来获取子元素节点。示例代码如下。

obj.children[0];// 获取第一个子元素节点
obj.children[obj.children.length - 1] // 获取最后一个子元素节点

3. 获取兄弟节点 nextSibling、previousSibling、nextElementSibling、previousElementSibling 属性

在 JavaScript 中,可以使用 nextSibling 属性来获得下一个兄弟节点,使用previousSibling 属性来获得上一个兄弟节点。它们的返回值包含元素节点或者文本节点等。如果找不到,就返回 null。

如果想要获得兄弟元素节点,则可以使用 nextElementSibling 返回当前元素的下一个兄弟元素节点,使用 previousElementSibling 属性返回当前元素的上一个兄弟元素节点。如果找不到则返回 null。

要注意的是,这两个属性有兼容性问题,IE9 以上才支持。

实际开发中,nextSibling 和 previousSibling 属性返回值都包含其他节点,操作不方便,而 nextElementSibing 和 previousElementSibling 又有兼容性问题。为了解决兼容性问题,在实际开发中通常使用封装函数来处理兼容性。

示例代码如下:

<!DOCTYPE HTML>
<html>
	<head>
		<meta charset="UTF-8">
		<title>测试</title>
	</head>
	<body>
		
		<script>
			
			function getNextElementSibling(element) {
				var el = element;
				while (el = el.nextSibling) {
					if(el.nodeType === 1) {
						return el;
					}
				}
				return null;
			}
			
		</script>
		
	</body>
</html>

上述代码中,定义了 getNextElementSibling() 函数,参数为 element。在 while 循环中,通过 if 条件语句进行判断,如果 nodeType 属性值等于 1,那么获取到的节点类型为元素节点。

7.4.3_[ 案例 ] 下拉菜单

下拉菜单在阿站中的应用非常广泛,例如,鼠标指针经过下拉菜单时,显示当前下拉框中的内容,并隐藏其他下拉菜单内容。具体实现步骤如下。

(1) 编写 HTML 代码完成页面布局。

<body>
<ul class="nav">
<li>
<a href="#">微博</a>
<ul>
<li><a href=""> 私信</a></li>
<li><a href=""> 评论</a></li>
<li><a href="">@ 我</a></li>
</u1>
</li>
...(此处省略3个li)
</u1>
</body>

上述代码采用 ul、li 的结构布局,ul 下有多个下拉菜单 li,每个 Ii 中有一个 a 和 ul 列表,a 为标签名,ul 为下拉内容。当鼠标指针经过 li 时,li 中的 ul 显示;当鼠标指针离开 li 时,li 中的 ul 隐藏。

(2) 鼠标指针经过时展示当前下拉列表内容,示例代码如下。

<script>
// 1.获取元素
var nav = document.querySelector('.nav');
var lis = nav.children;
// 2.注册鼠标指针经过和鼠标指针离开事件
for (var i = 0; i < lis.length; i++) {
lis[i].onmouseover = function() {
this.children[1].style.display = 'block'; // ul为li的第2个子元素
};
lis[i].onmouseout = function ()
this.children[1].style.display = 'none';
};
}
</script>

上述代码中,第 3、4 行代码获取类名为 nav 下的4个 li 。第 6 ~ 13 行代码使用 for 循环注册事件,其中第 7 ~ 9 行代码表示当鼠标指针经过时,设置当前 li 的第 2 个子元素 ul 显示;当鼠标指针离开时,则隐藏当前 li 的第 2 个子元素 ul 内容。

7.5_节点操作

7.5.1_创建节点

在获取元素的节点后,还可以利用 DOM 提供的方法实现节点的添加,如创建一个 li 元素节点,为 li 元素节点创建一个文本节点等。

在 DOM 中,使用 documentcreateElement(‘tagName’)方法创建由 tagName 指定的 HTML 元素。因为这些元素在原先是不存在的,是根据实际开发需求动态生成的,所以也称为动态创建元素节点。

动态创建元素节点有 3 种常见方式,具体如下。

( 1 ) document.write()

document.write() 创建元素,如果页面文档流加载完毕,再调用会导致页面重绘。

( 2 ) element.innerHTML

element.innerHTML 是将内容写入某个 DOM 节点,不会导致页面全部重绘。

( 3 ) document.createElement()

document.createElement() 创建多个元素时效率稍微低一点, 但是结构更加清晰。

7.5.2_添加和删除节点

在 DOM 中,提供了 node.appendChild() 和 node.insertBefore() 方法用于添加节点,node.removeChild(child) 用于删除节点。
接下来我们进行上述三种方法的使用讲解。

1. appendChild()

appendChild() 方法,将一个节点添加到指定父节点的子节点列表末尾,类似于 CSS 中的 after 伪元素。

2. insertBefore()

insertBefore (child,指定元素) 方法,将一个节点添加到父节点的指定子节点前面,类似于 CSS 中的 before 伪元素。

3. removeChild(child)

removeChild (child) 用于删除节点,该方法从 DOM 中删除一个子节点,返回删除的节点。

7.5.3_[ 案例 ] 简易留言板

案例:将利用节点的创建、添加和删除相关知识完成一个简易的留言板功能。在页面中实现单击 “ 发布 ” 按钮动态创建一个 li, 添加到 ul 里面。具体实现步骤如下。

(1) 编写 HTML 页面。

<!DOCTYPE HTML>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
	</head>
	<body>
		<textarea name="" id=""></textarea>
		<button>发布</button>
		<ul>
			</u1>
	</body>
</html>

在这里插入图片描述

上述代码中,定义了一个 textarea 多行文本输人框。供用户输入留言。
button 按钮用于单击发布留言。
ul 用于展示留言模块。

(2) 单击 “ 发布 ” 按钮,实现添加留言功能。

<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 {
// (1) 创建元素
var li = document.createElement('li');
li.innerHTML = text.value;
// (2) 添加元素
ul.insertBefore(li, ul.children[0]);
}
};
</script>

上述代码中,第 7 行代码给 button 按钮添加单击事件,用于添加留言。第 8 ~ 11 行代码使用 if 条件语句进行判断,如果用户输入为空,提醒用户进行输人,否则执行 else 代码块。第 13、14 行代码创建元素 li 并给创建好的元素 li 进行赋值。第 16 行代码把创建好的 li 放到第一个元素的前面。

(3) 修改上述代码,实现删除留言功能。

要实现留言的删除,首先在添加 li 后时,就需要给 li 中增加一个 a 链接,给所有的 a 链接注册单击事件,找到 a 的父节点 li ,进行删除即可。

修改第 (2) 步中第 14 行的代码,改为如下代码。

li.innerHIML = text.value + '<a href="javascript:;">删除</a>';

在第( 2 )步第 16 行代码之后添加删除留言代码,如下所示。

var as = document.querySelectorAll('a');
for (var i = 0; i < as.length; i++) {
as[i].onclick = function() {
ul.removeChild(this.parentNode);
};
}

上述代码中,第 1 行代码获取所有的 a 元素。第 2 行代码利用 for 循环给 a 元素注册单击事件。第 4 行代码使用 node. removeChild(child) 方法删除当前 a 所在的 li 。

7.5.4_复制节点 node.cloneNode() 方法

在 DOM 中,提供了 node.cloneNode() 方法,返回调用该方法的节点的一个副本,也称为克隆节点或者拷贝节点。语法为 “ 需要被复制的节点.cloneChild(true/false) " 。如果参数为空或 false ,则是浅拷贝,即只复制节点本身,不复制里面的子节点;如果括号参数为 true ,则是深拷贝,即会复制节点本身及里面所有的子节点。示例代码如下。

<body>
<ul id="myList"><li>苹果</li><li>橙子</li><li>橘子</li></u1>
<ul id="op"></ul>
<button onclick="myFunction()">点我</button>
<script>
function myFunction() {
var item = document.getElementById('mylist').firstChild;
var cloneItem = item.cloneNode (true);
document.getElementById('op').appendChild(cloneItem);
</script>
</body>

上述代码中,当单击 “ 点我 ” 按钮的时候,触发 myFunction() 函数,其中第 7 行代码获取 id 为 myList 列表中的第一个元素。 第 8 行代码调用 cloneNode(true) 方法,复制第 7 行获取到的元素 item。第 9 行代码获取 id 为 op 的元素,并使用 appendChild() 方法将复制完成的 cloneItem 节点添加到 id 为 op 的元素中。

修改上述第 8 行代码,把 cloneNode(true) 的参数 true 改为 flse ,运行结果:

运行结果

由上图可知,当参数为 false 时只有一个空的 li 元素被复制。

7.6_事件进阶

接下来我们将学习事件的相关操作内容。

7.6.1_注册事件

在JavaScript 中,注册事件(绑定事件)有两种方式,即传统方式注册事件和事件监听方式注册事件。下面我们分别进行讲解。

1.传统方式

在 JavaScript 代码中,经常使用 on 开头的事件 ( 如 onclick ),为操作的 DOM 元素对象添加事件与事件处理程序。具体语法格式如下。

元素对象.事件 = 事件的处理程序;
// 示例
oBtn.onclick = function() {  }

在上述语法中,元素对象是指使用 getElementByld() 等方法获取到的元素节点。使用这种方式注册事件的特点在于注册事件的唯一性, 即同一个元素同一个事件只能设置一个处理函数,最后注册的处理函数将会覆盖前面注册的处理函数。

  1. 事件监听方式

为了给同一个 DOM 对象的同一个事件添加多个事件处理程序,DOM 2 级事件模型中引人了事件流的概念,可以让 DOM 对象通过事件监听的方式实现事件的绑定。由于不同浏览器采用的事件流实现方式不同,事件监听的实现存在兼容性问题。通常根据浏览器的内核,可以把浏览器划分为两大类,一类是早期版本的 IE 浏览器( 如 IE6 ~ IE8),一类是遵循 W3C 标准的浏览器( 以下简称标准浏览器 )。

接下来我们将根据不同类型的浏览器,分别介绍事件监听的实现方式。

(1) 早期 IE 内核的浏览器

在早期版本的 IE 浏览器中,事件监听的语法格式如下。

DOM 对象.attachEvent (type, callback) ;

在上述语法中,参数 type 指的是为 DOM 对象绑定的事件类型,它是由 on 与事件名称组成的,如 onclick 。参数 callback 表示事件的处理程序。

(2) 标准浏览器

标准浏览器,包括 IE 8 版本以上的 IE 浏览器,以及新版的 Firefox、 Chrome 等浏览器。具体语法格式如下。

DOM 对象.addEventListener (type, callback, [capture]);

在上述语法中,参数 type 指的是 DOM 对象绑定的事件类型,它是由事件名称设置的,如 click。参数 callback 表示事件的处理程序。参数 capture 默认值为 false ,表示在冒泡阶段完成事件处理,将其设置为 true 时,表示在捕获阶段完成事件处理。

以上介绍的两种类型的浏览器,在实现事件监听时除了语法不同外,事件处理程序的触发顺序也不相同。早期版本 IE 浏览器的示例代码如下。

<div id="t">test</div>
<script>
var obj = document.getElementById('t');
// 添加第1个事件处理程序
obj.attachEvent ('onclick',function() {
console.log ('one');
});
// 添加第2个事件处理程序
obj.attachEvent('onclick'function() {
console.log('two');
});
</script>

标准浏览器的示例代码如下。

<div id="t">test</div>
<script>
var obj = document.getElementById('t');
// 添加第1个事件处理程序
obj.addEventListener('click', function() {
console.log ('one');
});
// 添加第2个事件处理程序
obj.addEventListener('click', function() { 
console.log ('two');
});
</script>

以上两种方式用于为 < div> 标签的单击事件添加两个处理程序,第 1 个处理程序在控制台输出one ,第 2 个处理程序在控制台输出 two。接下来我们在 test.html 文件中保存早期版本 IE 浏览器的相关事件监听代码,在 IE 11 的开发人员工具中,中,通过 IE 8 兼容模式来测试,

运行结果 128

从运行结果可以看出,同一个对象的相同事件,早期版本IE浏览器的事件处理程序按照添加的顺序倒序执行,因此输出结果依次为 two 和 one;而标准浏览器的事件处理程序按照添加顺序正序执行,因此输出的结果依次为 one 和 two。

7.6.2_删除事件

在保证事件监听的处理程序是一个有名的函数时,开发中可根据实际需求移出 DOM 对象的事件监听。同样,事件监听的移出也需考虑兼容性问题,具体语法格式如下。

DOM对象.onclick = null; // 传统方式删除事件
DOM对象.detachEvent(type, callback); // 早期版本IE浏览器
DOM对象.removeEventListener(type, callback); // 标准浏览器

在上述语法中,参数 type 值的设置要与添加事件监听的事件类型相同,参数 callback 表示事件处理程序的名称,即函数名。

7.6.3_DOM 事件流

事件发生时,会在发生事件的元素节点与 DOM 树根节点之间按照特定的顺序进行传播,这个事件传播的过程就是事件流。

在浏览器发展历史中,网景 (Netscape) 公司团队的事件流采用事件捕获方式,指的是事件流传播的顺序应该是从 DOM 树的最上层开始出发一直到发生事件的元素节点。而微软 ( Microsoft ) 公司的事件流采用事件冒泡方式,指的是事件流传播的顺序应该是:从发生事件的元素节点到 DOM 树的根节点。

W3C 对网景公司和微软公司提出的方案进行了中和处理,规定了事件发生后,首先实现事件捕获,但不会对事件进行处理;然后进行到目标阶段,执行当前元素对象的事件处理程序。但它会被看成是冒泡阶段的一部分;最后实现事件的冒泡,逐级对事件进行处理。

在这里插入图片描述

7.7_事件对象

7.7.1_什么是事件对象

当一个事件发生后,跟事件相关的一系列信息数据的集合都放到这个对象里面,这个对象就是 event。只有有了事件,event 才会存在,它是系统自动创建的,不需要传递参数。
事件对象是事件一系列相关数据的集合, 例如, 鼠标单击的事件对象,就包含了鼠标的相关信息,如鼠标指针坐标等。如果是键盘事件,事件对象中就包含键盘事件的相关信息,例如,用户按下了哪个键,事件对象中就会包括按下键的键值等相关信息。

7.7.2_事件对象的使用

虽然所有浏览器都支持事件对象 event,但是不同的浏览器获取事件对象的方式不同。

在标准浏览器中会将一个 event 对象直接传入到事件处理程序中,而早期版本的 IE 浏览器 ( IE 6 ~ IE 8)中,仅能通过 window.event 才能获取事件对象,语法格式如下。

var 事件对象 = window.event // 早期IE内核浏览器
DOM 对象.事件 = function (event) {  } // W3C内核浏览器

上述代码中,因为在事件触发时就会产生事件对象,并且系统会以实参的形式传给事件处理函数。所以,在事件处理函数中需要用个形参来接收事件对象 event。

案例:以获取 button 按钮单击事件的事件对象为例演示,

<!DOCTYPE HTML>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
	</head>
	<body>
		
		<button id="btn">获取event对象</button>
		
		<script>
			
			var btn = document.getElementById('btn');
			btn.onclick = function(e) {
				var event = e || window.event; // 获取事件对象的兼容处理
				console.log(event);
			}
			
		</script>
			
	</body>
</html>

在这里插入图片描述
点击按钮后,
在这里插入图片描述

上述代码中,根据 id 属性值获取 button 按钮的元素对象。
通过动态绑定式为按钮添加单击事件。其中,事件处理函数中传递的参数 e ( 参数名称只要符合变量定义的规则即可 ) 表示的就是事件对象 event 。
通过 “ 或 ” 运算符实现不同浏览器间获取事件对象兼容的处理。若是标准浏览器,则可以直接通过 e 获取事件对象;若是早期版本的 IE 浏览器 (IE 6 ~ IE 8) 则需要通过 window.event 才能获取事件对象。

7.7.3_事件对象的常用属性和方法

在事件发生后,事件对象 event 中不仅包含着与特定事件相关的信息,还会包含一些所有事件都有的属性和方法。

事件对象的常用属性和方法

属性说明浏览器
e.target返回触发事件的对象标准浏览器
e.srcElement返回触发事件的对象非标准 IE6 ~ IE8 使用
e.type返回事件的类型所有浏览器
e.stopPropagation()阻止事件冒泡标准浏览器
e.cancelBubble阻止事件冒泡非标准 IE6 ~ IE8 使用
e.preventDefault()阻止默认事件(默认行为)标准浏览器
e.returnValue阻止默认事件(默认行为)非标准 IE6 ~ IE8 使用

在上表中,type 是标准浏览器和早期版本 IE 浏览器的事件对象的公有属性,通过该属性可以获取发生事件的类型,如 click、mouseover 等 ( 不带on )。

在讲解了事件对象常用的属性和方法后,接下来我们将针对常见的使用场景进行讲解。

1. 对比 e.target 和 this 的区别

在事件处理函数中,e.target 返回的是触发事件的对象,而 this 返回的是绑定事件的对象。简而言之,e.target 是哪个元素触发事件了,就返回哪个元素;而 this 是哪个元素绑定了这个事件,就返回哪个元素。

考虑 e.target 在 IE9 以上才支持,所以编写以下代码,处理兼容性问题,

没看明白

<!DOCTYPE HTML>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
	</head>
	<body>		
		
		<script>
			
			div.onclick = function(e) {
				e = e || window.event;
				var target = e.target || e.srcElement;
				console.log(target);
			}
			
		</script>
			
	</body>
</html>

值得一提的是,this 和 e.currentTarget 的值相同,但考虑到 e.currentTarge 有兼容性问题 ( IE9 以上支持 ),所以在实际开发中推荐使用 this。

2. 阻止默认行为

在 HTML 中,有些元素标签拥有一些特殊的行为。 例如, 单击 < a> 标签后,会自动跳转到 href 属性指定的 URL 链接;单击表单的 submit 按钮后,会自动将表单数据提交到指定的服务器端页面处理。因此,我们把标签具有的这种行为称为默认行为。

但是在实际开发中,为了使程序更加严谨,希望确定含有默认行为的标签符合要求后,才能执行默认行为时,可利用事件对象的 preventDefault() 方法和 returnValue 属性,禁止所有浏览器执行元素的默认行为。需要注意的是,只有事件对象的 cancelable 属性设置为 true ,才可以使用 preventDefault() 方法取消其默认行为。

案例:以禁用 < a> 标签的链接为例进行演示,

<body>
<a href="http://www.baidu.com">百度</a>
<script>
var a = document.querySelector('a');
a.addEventListener('click', function (e) {
e.preventDefault(); // DOM标准写法,早期版本浏览器不支持
});
//推荐使用传统的注册方式
a.onclick = function (e) {
e.preventDefault();  // 标准浏览器使用e.preventDefault()方法
e.returnValue;  // 早期版本浏览器(IE6 ~ IE8)使用returnValue属性
};
</script>
</body>

上述代码中,第 4 行代码获取 a 链接对象。第 5 ~ 7 行代码使用 addEventListener 注册单击事件。第 6 行通过 e.preventDefault 方法阻止 a 链接进行跳转,但是在早期版本浏览器中不支持该写法,所以在第 9 ~ 12 行使用传统注册方式绑定 click 单击事件。其中,第10 行针对标准浏览器使用 preventDefault() 方式,第 11 行针对低版本浏览器使用 returnValue 属性。

值得一提的是,针对于传统注册方式绑定事件,也可以使用 returnfalse 来阻止默认事件。优点在于没有兼容性问题,缺点是 return 后面的代码不执行,而且只限于传统的注册方式。

  1. 阻止事件冒泡

如果在开发中想要阻止事件冒泡,则可以利用事件对象调用 stopPropagation() 方法和设置 cancelBubble 属性,实现禁止所有浏览器的事件冒泡行为。

例如,为单击事件的事件处理程序添加参数 e,用于获取事件对象,并且在控制台输出前添加以下代码。

if (window.event) {  // 早期版本的浏览器
window.event.cancelBubble = true;
} else {       // 标准浏览器
e.stopPropagation();
}

上述第 1 行代码用于判断当前是否为早期版本的 IE 浏览器,如果是,则利用事件对象调用 cancelBubble 属性阻止事件冒泡;否时利用事件对象 e 调用 stopPropagation() 方法完成事件冒泡的阻止设置。

  1. 事件委托

在现实生活中,有时快递员为了节省时间,会把快递放到某快递代收机构,然后让客户自行去领取,这种把事情委托给别人的方式,就是代为处理。事件委托 ( 或称为事件代理 ) 也是如此。事件委托的原理是,不给每个子节点单独设置事件监听器,而是把事件监听器设置在其父节点上,让其利用事件冒泡的原理影响到每个子节点。简而言之,就是不给子元素注册事件,给父元素注册事件,让处理代码在父元素的事件中执行。这样做的优点在于,操作了一次 DOM ,提高了程序的性能。

案例:演示事件委托的使用,

<body>
<ul>
<li>我是第1个li</li>
<li>我是第2个li</li>
<li>我是第3个li</li>
<li>我是第4个li</li>
<li>我是第5个li</li>
</u1>
<script>
var ul = document.querySelector('ul');
ul.addEventListener('click', function (e) {
e.target.style.backgroundColor = 'pink';
});
</script>
</body>

上述代码中,第 10 ~ 13 行代码采用事件委托原理,首先获取到 ul 父元素,并且在第 11 行给父元素绑定单击事件,实现单击子元素 li 时,给当前项改变背景色。

7.8_鼠标事件

7.8.1_鼠标事件的常用方法

鼠标是计算机的一种输入设备, 也是计算机显示系统纵横坐标定位的指示器,所以鼠标事件是 Web 开发中最常用的一类事件。例如,鼠标指针滑过时,切换 Tab 栏显示的内容;利用鼠标拖电状态框,调整显示位置等,这些常见的网页效果都会用到鼠标事件。

鼠标事件:

事件名称事件触发时机
onclick单击鼠标左键时触发
onfocus获得鼠标指针焦点触发
onblur失去鼠标指针焦点触发
onmouseover鼠标指针经过时触发
onmouseout鼠标指针离开时触发
onmousedown当按下任意鼠标按键时触发
omouseup当释放任意鼠标按键时触发
onmousemove在元素内当鼠标指针移动时持续触发

上表中列举的这此鼠标事件的使用都非常简单,读者可以自行尝试使用。
在项目开发中,有时还会用到 contextmenu 和 selectstart 这两个事件,接下来我们将分别进行详解。

1. 禁止鼠标右击菜单 ( contextmenu )

contextmenu 主要控制应该何时显示上下文菜单,主要应用于程序员取消默认的上下文菜单,示例代码如下。

document.addEventListener ('contextmenu', function (e) {
e.preventDefault();
});

2. 禁止鼠标选中 ( selectstart 事件 )

selectstart 事件是鼠标开始选择文字时就会触发,如果禁止鼠标选中,需要禁止该事件的默认行为,示例代码如下。

document.addEventListener ('selectstart', function (e) {
e.preventDefault();
});

7.8.2_鼠标事件对象

之前我们学习了 event 事件对象,它代表事件的状态,是跟事件相关的一系列信息的集合,现阶段主要使用的是鼠标事件对象 MouseEvent。

在项目开发中还经常涉及一些常用的鼠标属性,用来获取当前鼠标指针的位置信息。

鼠标事件位置属性:

位置属性(只读)描述
clientX鼠标指针位于浏览器页面当前窗口可视区的水平坐标 ( X轴坐标 )
clientY鼠标指针位于浏览器页面当前窗口可视区的垂直坐标 ( Y轴坐标 )
pageX鼠标指针位于文档的水平坐标(X轴坐标),IE6 ~ IE8 不兼容
pageY鼠标指针位于文档的垂直坐标(Y轴坐标),IE6 ~ IE8 不兼容
screenX鼠标指针位于屏幕的水平坐标(X轴坐标)
screenY鼠标指针位于屏幕的垂直坐标(Y轴坐标)

从上表可知,IE6 ~ IE8 浏览器中不兼容 pageX 和 pageY 属性。因此,项目开发时需要对 IE6 ~ IE8 浏览器进行兼容处理,具体示例如下。

var pageX = event.pageX || event.clientX + (document.body.scrollLeft || document.documentElement.scrollLeft);
var pageY = event.pageY || event.clientY + (document.body.scrollTop || document.documentElement.scrollTop);

从以上代码可知,鼠标指针在文档中的坐标等于鼠标指针在当前窗口中的坐标加上滚动条卷去的文本长度,需要用到 doeument.body 或者 document.documentElement 下的 srollLeft 和 scrollTop 属性。

7.8.3_[ 案例 ] 图片跟随鼠标指针移动

本案例将在不考虑兼容性的情况下,简单实现图片跟随鼠标指针移动的效果。在这里需要使用鼠标移动事件 mousemove ,每次鼠标移动,都会获得最新的鼠标指针坐标,把这个 x 和 y 坐标作为图片的 top 和 left 值就可以实现图片的移动。

案例:示例代码如下。

<style>
img {
position: absolute;
top: 2px;
}
</style>
<body>
<img src="images/angel.gif" alt="">
<script>
var pic = document.querySelector ('img');
document.addEventListener ('mousemove', function(e) {
var x = e.pageX;
var y = e.pageY;
pic.style.left = x - 50 + 'px';
pic.style.top = y - 40 + 'px';
});
</script>
</body>

上述代码中,第 1 ~ 6 行代码给 img 图片设置定位,因为图片要移动,不占位置,所以这里使用绝对定位即可。第 11 行由于图片是在页面中移动,所以要为 document 添加 mousemove 事件,在事件处理程序中,获取鼠标的 X、Y 坐标,然后把 X、Y 坐标作为图片的 top 和 left 值。需要注意的是,要给 left 和 top 属性添加 px 单位。

7.9_键盘事件

7.9.1_键盘事件的常用方法

键盘事件是指用户在使用键盘时触发的事件。例如,用户按 Esc 键关闭打开的状态栏,按 Enter 键直接完成光标的上下切换等。

键盘事件:

事件名称事件触发时机
keypress某个键盘按键被按下时触发。不识别功能键,如Ctrl、 Shift、 箭头等
keydown某个键盘按键被按下时触发
keyup某个键盘按键被松开时触发

需要注意的是,keypress 事件保存的按键值是 ASCII 码,keydown 和 keyup 事件保存的按键值是虚拟键码,keydown 和 keypress 如果按住不放的话,会重复触发该对应事件。keyup 和 keydown 事件不区分字母大小写,而 keypress 区分字母大小写。

在发生 keydown 和 keypress 事件时,event 事件对象的 keycode 属性会包含一一个值,该值与键盘上的特定值对应。keycode 的值与 ASCII 码对应的值相同,例如,keycode 值为13 表示 Enter 键,keycode 值为 9 表示 Tab 键。读者可参考 MDN 等手册进行查看,此处不再详细列举。

7.9.2_键盘事件对象

键盘事件也有相应的键盘事件对象 KeyBoardEvent,该对象是跟键盘事件相关的一系列信息的集合。根据键盘事件对象中的 keyCode 属性可以得到相应的 ASCII 码值,进而可以判断用户按下了哪个键。

案例:检测用户是否按下了 s 键,如果按下 s 键,就把光标定位到搜索框里面,

<body>
<input type="text">
<script>
var search = document.querySelector('input');
document.addEventListener('keyup', function (e) {
if (e.keyCode == 83) {
search.focus ();
}
});
</script>
</body>

上述代码中,第 5 行代码绑定了鼠标弹起事件,当输入完毕后再进行检测。第 6 ~ 8 行代码使用键盘事件对象里面的 keyCode 判断用户按下的是否是 s 键,如果是,则让搜索框获取焦点,帮助用户进行输入。

7.9.3_[ 案例 ] 文本框提示信息

在现实生活中,我们经常会使用快递单号查询功能,查看商品的物流信息状态。有时在用户输人单号时,网站为了让用户看清楚输人的内容,会在文本框上方显示一个提示栏,将用户输人的数字放大,

案例:为当用户在文本框中输人内容时,文本框上面自动显示大号字的内容。如果用户输人为空,需要隐藏大号字内容。本案例的具体实现步骤如下,

(1) 编写 HTML 代码完成页面布局。

<body>
<div class="search">
<div class="con"></div>
<label>快递单号:
<input type="text" placeholder="请输人您的快递单号" class="num">
</label>
</div>
</body>

上述代码中,第 3 行代码定义了类名为 con 的 div 元素,用来显示用户输人的大号字内容。第 5 行的 < input> 标签用来显示用户输入内容。

(2) 检测用户输人,给表单添加键盘事件,示例代码如下。

<script>
var con = document.querySelector('.con');
var numInput = document.queryselector('.num');
numInput.addEventListener('keyup', function () {
if (this.value == '' ) {
con.style.display = 'none';
} else {
con.style.display = 'block';
con.innerText = this.value;
}
});
</script>

上述代码中,第 2、3 行代码获取 con 和 num_input 对象。第 4 行代码为给 numInput 表单对象添加 keyup 事件,在用户输入完毕之后,进行内容检测。第 5 ~ 10 行代码为通过 if 语句进行判断,如果输人内容为空,则隐藏 con 元素,否则显示 con 元素,同时把快递单号里面的值 ( value ) 获取过来赋值给 con 盒子 ( innerText) 作为内容。

(3) 失去焦点,隐藏 con 元素。

在第 (2) 步的第 11 行之后,编写如下代码,实现文本框失去焦点,隐藏 con 元素。

num_input.addEventListener('blur', function() {
con.style.display = 'none';
});

(4) 获得焦点,显示con元素。

在第 (3) 步代码之后,编写如下代码,实现文本框获取焦点,显示 con 元素。

num input.addEventListener('focus', function ) {
con.style.display = 'block';
});

完成上述代码后,通过浏览器访问测试即可。

今日入门学习暂时告一段落
Peace

🌊🌈往期回顾:

JavaScript学习:
挑战最短时间内带你入门 JavaScript(一)
挑战最短时间内带你入门 JavaScript(二)
挑战最短时间内带你入门 JavaScript(三)
挑战最短时间内带你入门 JavaScript(四)
【干货分享|建议收藏】2w字爆肝详解 JavaScript对象
【建议收藏|熬夜爆肝】万字文带你了解DOM,文末有彩蛋嗷!!!✨✨✨

HTML学习:
阿ken的HTML、CSS的学习笔记_HTML基础(笔记一)
阿ken的HTML、CSS的学习笔记_HTML 页面元素和属性(笔记二)
阿ken的HTML、CSS的学习笔记_文本样式属性(笔记三)
阿ken的HTML、CSS的学习笔记_CSS3选择器(笔记四)
阿ken的HTML、CSS的学习笔记_CSS盒子模型(笔记五)
阿ken的HTML、CSS的学习笔记_浮动与定位(笔记六)
阿ken的HTML、CSS的学习笔记_表单的应用(笔记七)
阿ken的HTML、CSS的学习笔记_多媒体技术(笔记八)
阿ken的HTML、CSS的学习笔记_CSS3高级应用(笔记九)

🌊🌈关于后记:

感谢阅读,希望能对你有所帮助 博文若有瑕疵请在评论区留言或在主页个人介绍中添加联系方式私聊我 感谢每一位小伙伴不吝赐教
原创不易,「点赞」+「关注」+「收藏」 谢谢支持❤

  • 100
    点赞
  • 74
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 88
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 88
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

请叫我阿ken

观众老爷要是看的开心还请支持下

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值