DOM 和 BOM
什么是 DOM 操作?
- DOM 操作指的是在编程中,尤其是在网页和应用开发中,使用 JavaScript 等脚本语言对文档对象模型(Document Object Model,简称DOM)进行的各种操作。DOM 是一种以树形结构表示文档的编程接口,它让程序能够动态地访问和更新文档的结构、样式和内容。
- DOM 操作通常包括以下几种活动:
- 节点创建:可以创建新的元素或节点,并将其插入到DOM树中。
- 节点插入:在 DOM 树中的特定位置插入一个节点。
- 节点删除:从 DOM 树中移除一个节点。
- 节点替换:用一个新的节点替换 DOM 树中的一个现有节点。
- 节点查询:查找 DOM 树中的元素或节点,通常使用选择器(如CSS选择器)。
- 属性修改:改变节点的属性,例如改变一个链接的
href
属性或一个图像的src
属性。 - 样式修改:改变节点的样式,例如颜色、字体大小等CSS属性。
- 事件处理:为节点添加事件监听器来响应用户操作,如点击、按键、鼠标移动等。
- DOM 操作是动态网页交互的基础,它使得开发者能够编写脚本来实时地改变文档内容,而无需重新加载整个页面。这是现代网页应用不可或缺的一部分,负责驱动用户界面的交互性和动态特性。
查找元素(一)
-
通过ID查找元素
这个方法会返回一个具有指定ID的元素。由于ID在一个文档中应该是唯一的,所以这个方法返回单个元素。
1
var element = document.getElementById('elementId');
-
通过类名查找元素集合
这个方法会返回一个类数组对象(HTMLCollection),包含文档中所有具有指定类名的元素。
1
var elements = document.getElementsByClassName('className');
-
通过标签名查找元素集合
这个方法会返回一个包含所有指定标签名的元素的类数组对象。
1
var elements = document.getElementsByTagName('tagName');
-
通过 name 属性查找元素集合
1
var elements = document.getElementsByName('elementName');
-
通过 CSS 选择器查找单个元素
这个方法会返回文档中匹配指定CSS选择器的第一个元素。
1
var element = document.querySelector('.className');
-
通过 CSS 选择器查找元素集合
这个方法会返回一个NodeList对象,包含文档中所有匹配指定CSS选择器的元素。
1
var elements = document.querySelectorAll('.className');
-
属性选择器查找元素
这个方法会返回一个NodeList对象,包含所有具有指定属性和值的元素。
1
var elements = document.querySelectorAll('[attribute=value]');
-
综合示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
<html lang="en">
<head>
<meta charset="UTF-8">
<title>DOM操作示例</title>
</head>
<body>
<div id="container">
<form name="registration">
<input type="text" name="username" placeholder="Username" />
<input type="password" name="password" placeholder="Password" />
<input type="submit" value="Register" />
</form>
<div class="content" name="article">This is a content section.</div>
<div class="content" name="article">Another content section.</div>
<p>Here is a list of items:</p>
<ul>
<li class="item">Item 1</li>
<li class="item">Item 2</li>
<li class="item">Item 3</li>
</ul>
</div>
<script>
// 通过ID查找
var containerDiv = document.getElementById('container');
// 通过name查找
var registrationForm = document.getElementsByName('registration')[0];
var usernameInputs = document.getElementsByName('username');
// 通过类名查找
var contentDivs = document.getElementsByClassName('content');
// 通过标签名查找
var listItems = document.getElementsByTagName('li');
// 使用querySelector查找第一个匹配的元素
var firstContentDiv = document.querySelector('.content');
// 使用querySelectorAll查找所有匹配的元素
var allItems = document.querySelectorAll('.item');
// 打印找到的元素以确认
console.log(containerDiv);
console.log(registrationForm);
console.log(usernameInputs);
console.log(contentDivs);
console.log(listItems);
console.log(firstContentDiv);
console.log(allItems);
// 遍历NodeList示例
for (var i = 0; i < contentDivs.length; i++) {
console.log(contentDivs[i].textContent); // 打印内容区块的文本内容
}
</script>
</body>
</html>
JS 事件
-
用户界面事件
-
load
: 网页加载完成时触发。load
事件在文档及其依赖资源(如图像、样式表等)完全加载并解析完成后触发。load
事件常用于执行那些需要在页面完全加载后才能进行的操作,比如初始化脚本、启动动画或者根据用户的屏幕尺寸调整布局等。- 下面是一个
load
事件的示例,它在window
对象上设置了监听器,以确保在执行任何脚本前页面内容已经载入完毕:1
2
3
4
5window.addEventListener('load', function () {
// 页面的所有资源包括图片、样式等都已完全加载
console.log('所有资源加载完成!');
// 在这里执行页面初始化需要的代码
}); - 使用
addEventListener
方法添加监听器的好处是可以添加多个监听器,而不会覆盖之前已经注册的事件处理函数。另外,这种方式比使用onload
属性更灵活、更具有可维护性。 - 除了
window
对象,load
事件也可以用于单独的资源,比如图像:1
2
3
4
5
6
7
8
9var image = new Image();
image.addEventListener('load', function () {
// 图片加载完成
console.log('图片加载完成!');
document.body.appendChild(image); // 将图片添加到文档中
});
image.src = 'path/to/your/image.jpg'; // 设置图片的source,开始加载图片 - 在上述代码中,我们创建了一个
Image
对象,为它添加了load
事件的监听器,然后设置了其src
属性以开始下载图片。一旦图片下载并加载完成,就会触发load
事件,并执行我们定义的回调函数。在这个回调函数内,我们将加载完成的图片添加到了文档的body
中。
-
unload
: 用户离开页面时触发。- 事件
unload
在用户即将离开页面时触发。这个事件通常用于执行清理任务,如关闭弹出窗口或释放对象等。然而,需要注意的是,由于安全和性能的原因,现代浏览器限制了在unload
事件期间可以执行的操作,特别是不推荐在此时间点进行同步的Ajax调用或者使用localStorage
。 - 以下是使用
unload
事件的一个基本示例:1
2
3
4
5
6window.addEventListener('unload', function (event) {
// 在这里执行清理操作
console.log('页面正在被卸载...');
// 注意:在大多数浏览器中,这里的 console.log 不会在控制台显示,
// 因为页面正在关闭,而且不允许延误用户的离开。
}); - 在实践中,
unload
事件可能不太可靠,因为它可能不会在所有情况下都触发(例如,如果浏览器崩溃或者用户关闭了浏览器)。另外,如前所述,浏览器可能不允许某些操作执行,因此不要依赖此事件来保存关键数据。 - 更现代的替代方法是使用
beforeunload
事件,这可以在关闭页面前询问用户是否真的想要离开。例如:1
2
3
4window.addEventListener('beforeunload', function (event) {
// 设置确认对话框的文本
event.returnValue = '您有未保存的更改,确定要离开吗?';
}); beforeunload
事件允许你提示用户确认他们是否真的想要离开页面。这对于编辑器或表单等情况特别有用,用户可能有正在编辑的未保存更改。但请注意,出于用户体验考虑,很多现代浏览器要求beforeunload
事件处理器在页面上真的进行了一些交互之后才能触发这样的提示,以防止滥用。
- 事件
-
resize
: 窗口或框架被重新调整大小时触发。resize
事件在窗口或框架被重新调整大小时触发。此事件常用于响应浏览器窗口大小的变化,执行一些布局调整或功能上的优化。例如,你可能需要根据窗口大小的不同来调整元素的尺寸,或是重新计算布局。- 以下是如何使用
resize
事件的一个例子:1
2
3
4
5
6
7
8
9
10
11
12window.addEventListener('resize', function (event) {
// 浏览器窗口大小发生变化
console.log('窗口大小已更改!');
var newWidth = window.innerWidth;
var newHeight = window.innerHeight;
// 根据新的窗口尺寸执行操作
console.log(`新的窗口宽度:${newWidth}, 新的窗口高度:${newHeight}`);
// 例如,你可以根据窗口大小调整某个元素的大小或展示方式
// document.getElementById('someElement').style.width = newWidth + 'px';
}); - 在这个例子中,当用户调整浏览器窗口大小时,回调函数会被调用,并在控制台输出新的窗口宽度和高度。你可以根据这个新尺寸来调整页面布局或执行其他响应式设计的操作。
- 请注意,
resize
事件在窗口大小改变时会频繁触发,所以处理函数中的代码应该尽量简洁,避免执行复杂或耗时的操作。如果需要进行较为复杂的计算或DOM更新,考虑使用防抖(debounce)或节流(throttle)技术来限制事件处理函数的调用频率,以提高性能。
-
scroll
: 用户滚动页面的滚动条时触发。scroll
事件在元素或文档滚动时触发。这个事件可以用来检测用户何时滚动页面或一个特定的元素,并据此执行相应的逻辑,比如懒加载图片、显示或隐藏页面上的元素、或者更新滚动位置的指示器。- 以下是一个使用
scroll
事件的例子:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18// 假设我们有一个滚动条在页面的右侧
window.addEventListener('scroll', function () {
// 页面滚动时,这个函数会被触发
// 获取当前滚动的位置
var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
// 根据滚动的距离执行相应的操作
console.log(`页面已经垂直滚动了 ${scrollTop} 像素`);
// 例如,当用户向下滚动超过一定距离时,显示"回到顶部"的按钮
var backButton = document.getElementById('back-to-top');
if (scrollTop > 500) {
backButton.style.display = 'block'; // 显示按钮
} else {
backButton.style.display = 'none'; // 隐藏按钮
}
}); - 在这个示例中,我们给
window
对象添加了一个scroll
事件的监听器,以便在页面滚动时执行一些操作。当页面垂直滚动时,我们计算了滚动的距离并在控制台输出。我们也根据滚动的距离来显示或隐藏一个“回到顶部”的按钮。 - 需要注意的是,
scroll
事件在滚动期间可能会被频繁地触发,这可能导致性能问题。为了避免这些问题,可以通过防抖(debouncing)或节流(throttling)技术来减少事件处理函数的调用频率。防抖是指在事件停止触发一段时间后才执行一次函数,而节流是指确保函数以固定的频率执行。这两种技术都可以帮助提高应用程序的性能和用户体验。
-
-
焦点事件
-
focus
: 元素获得焦点时触发。focus
事件在用户将输入焦点移至元素上时触发,通常用于<input>
,<select>
,<textarea>
等表单元素,以及任何设置了tabindex
属性的元素。这个事件可以用于例如,高亮显示当前选中的输入字段,初始化日期选择器,或者显示额外的指导信息。- 下面是一个使用
focus
事件的示例,它展示了如何在文本输入框获得焦点时改变其背景色:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15// 获取文本输入框元素
var input = document.getElementById('myInput');
// 为该元素添加focus事件监听器
input.addEventListener('focus', function (event) {
// 当元素获得焦点时,改变背景颜色
event.target.style.backgroundColor = 'lightblue';
// 可以在此处添加更多的逻辑,比如显示帮助文本、启动某个动画等
});
// 为了完整性,添加blur事件以在元素失去焦点时还原背景色
input.addEventListener('blur', function (event) {
event.target.style.backgroundColor = '';
}); - 在这个例子中,我们首先获取了 ID 为
myInput
的文本输入框元素,然后为它添加了一个focus
事件的监听器。当用户点击这个文本框,使其成为焦点时,文本框的背景色会变为浅蓝色,以此提醒用户当前输入的位置。为了在用户输入完成并将焦点从文本框移开时还原背景颜色,我们还添加了一个blur
事件的监听器。
-
blur
: 元素失去焦点时触发。blur
事件在元素失去焦点时触发。这通常发生在用户点击了一个元素以外的区域,或者通过键盘(比如 Tab 键)导航离开了元素。blur
事件对于处理表单验证、关闭激活的下拉菜单、防止意外的交互以及其他需要在用户离开特定元素时执行的任务非常有用。- 以下是
blur
事件的一个示例,展示了如何在文本输入框失去焦点时执行验证:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18// 获取文本输入框元素
var input = document.getElementById('myInput');
// 为该元素添加 blur 事件监听器
input.addEventListener('blur', function (event) {
// 元素失去焦点时执行代码
// 简单的验证:检查输入框是否为空
if (event.target.value.trim() === '') {
// 如果为空, 改变边框颜色为红色并显示警告信息
event.target.style.borderColor = 'red';
// 可能还会显示一些错误信息或其他视觉反馈
alert('此字段不能为空!');
} else {
// 如果不为空, 将边框颜色重置
event.target.style.borderColor = 'initial';
}
}); - 在这个例子中,我们首先获取了一个 ID 为
myInput
的文本输入框元素。然后,我们为它添加了一个blur
事件的监听器。当用户从输入框中移开焦点时(比如点击输入框外的区域或按下 Tab 键),如果输入框为空,边框将会变红,并且会弹出一个警告信息提示用户此字段不能为空。如果字段不为空,则输入框边框颜色重置为默认颜色。 - 使用
blur
事件可以帮助提高用户的填表体验,因为它允许及时发现并更正错误,而不必等到整个表单提交后才知道。需要注意的是,blur
事件不会冒泡,但是它支持捕获。如果需要在事件传播时捕获blur
事件,可以在addEventListener
的第三个参数中设置为true
。
-
-
鼠标事件
-
click
: 用户点击元素时触发。click
事件是 Web 开发中最常用的事件之一,它在用户点击元素时触发。这通常适用于按钮、链接、表单元素等可交互的元素。click
事件可以用来执行各种交互任务,如提交表单、打开模态窗口、触发动画等。- 以下是一个使用
click
事件的示例,它展示了如何在按钮被点击时弹出一个警告框:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Click Event Example</title>
</head>
<body>
<!-- 创建一个按钮 -->
<button id="myButton">点击我</button>
<script>
// 获取按钮元素
var button = document.getElementById('myButton');
// 为按钮添加click事件监听器
button.addEventListener('click', function (event) {
// 按钮点击时触发的动作
alert('按钮被点击了!');
});
</script>
</body>
</html> - 在这个简单的 HTML 文档中,我们定义了一个按钮元素,并且给它设置了一个唯一的 ID,这样我们就可以在 JavaScript 中引用它。在
<script>
标签中,我们首先获取了这个按钮的引用,然后使用addEventListener
方法为它添加了一个click
事件的监听器。当按钮被点击时,会执行一个匿名函数,这个函数简单地弹出一个包含文本 “按钮被点击了!” 的警告框。 - 这种模式可以扩展到更复杂的交互中,
click
事件通常是用户与网页交互的主要方式,你可以通过这个事件来触发几乎任何你希望在用户点击某个元素时发生的行为。
-
dblclick
: 用户双击元素时触发。dblclick
事件在用户双击一个元素时触发。dblclick
主要用于提供与click
事件不同的用户体验。例如,在一个文本编辑器中,单击可能会将光标定位到点击的位置,而双击可能会选择单词或段落。dblclick
事件不如click
事件常用,因为它不那么直观,但在某些情况下,双击操作可以为用户提供快速的交互方式。- 以下是一个使用
dblclick
事件的简单示例,展示了如何在用户双击页面上的段落时更改文字颜色:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<html lang="en">
<head>
<meta charset="UTF-8">
<title>dblclick Event Example</title>
</head>
<body>
<!-- 创建一个段落 -->
<p id="myParagraph">双击这段文字可以改变它的颜色。</p>
<script>
// 获取段落元素
var paragraph = document.getElementById('myParagraph');
// 为段落添加dblclick事件监听器
paragraph.addEventListener('dblclick', function (event) {
// 双击段落时触发的动作
event.target.style.color = 'blue'; // 将文字颜色改变为蓝色
});
</script>
</body>
</html> - 在这个例子中,用户在网页上双击 ID 为
myParagraph
的段落时,这个段落的文字颜色会改变为蓝色。通过event.target
,我们能够获取到触发事件的元素,并更改其样式。 - 这个例子中的双击交互相对简单直观,但实际应用中需要注意的是,考虑到用户的体验和现代设备的多样性(如触摸屏设备),
dblclick
事件可能不总是最佳的交互方式。在设计用户界面时,应该确保双击操作不会对那些期待单击行为的用户造成混淆。
-
mousedown
: 用户按下鼠标按键时触发。mousedown
事件在用户按下任何鼠标按钮时触发(不需要释放)。这使得mousedown
事件特别适合在用户开始点击过程中就需要响应的情况,比如拖放操作的开始或者在游戏中进行快速反应。与click
事件不同,click
事件只在用户完成鼠标按下并释放的整个动作之后才会触发。- 这种方式很实用,因为它给予了即时的视觉反馈,说明用户的操作被接受了。在用户界面设计中,这种模式可以用于提升用户交互的响应性和直观性。
-
mouseup
: 用户释放鼠标按键时触发。mouseup
事件在用户释放鼠标按钮时触发,无论是左键、中键还是右键。这个事件经常与mousedown
事件一起使用,以便处理完整的点击动作。例如,在拖放操作中,mousedown
可以用来开始拖动,而mouseup
可用来放置(释放)拖动的元素。另外,在需要区别单击和长按动作的场景,mouseup
可以搭配mousedown
来使用。- 示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<html lang="en">
<head>
<meta charset="UTF-8">
<title>mouseup Event Example</title>
</head>
<body>
<!-- 创建一个按钮 -->
<button id="myButton">按住并释放我</button>
<script>
// 获取按钮元素
var button = document.getElementById('myButton');
// 为按钮添加 mousedown 事件监听器,改变按钮的外观
button.addEventListener('mousedown', function (event) {
event.target.style.transform = 'scale(0.9)'; // 缩小按钮的尺寸
event.target.style.backgroundColor = 'red'; // 改变背景颜色为红色
});
// 为按钮添加 mouseup 事件监听器,恢复按钮的外观
button.addEventListener('mouseup', function (event) {
event.target.style.transform = ''; // 恢复按钮的尺寸
event.target.style.backgroundColor = ''; // 恢复背景颜色
});
</script>
</body>
</html> - 在这段代码中,当用户按下按钮时,
mousedown
事件监听器会减小按钮的尺寸并将其背景色改为红色,模拟按钮被按下的效果。随后,当用户释放鼠标按钮时,mouseup
事件监听器会被触发,恢复按钮的尺寸和背景色,给用户一个视觉上的反馈,表明按钮点击动作已完成。 - 这个交互模式非常直观,它通过视觉反馈让用户清楚地知道他们的动作起了作用。在设计用户界面时,这种即时的视觉反馈可以增强用户体验。
-
mousemove
: 鼠标在元素上移动时触发。mousemove
事件在鼠标指针移动时被触发,通常用于跟踪鼠标位置或实现拖拽效果。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<html lang="en">
<head>
<meta charset="UTF-8">
<title>mousemove Event Example</title>
</head>
<body>
<!-- 创建一个用于显示鼠标位置的元素 -->
<p id="mousePosition">移动鼠标</p>
<script>
// 在整个页面上添加 mousemove 事件监听器
document.addEventListener('mousemove', function (event) {
var x = event.clientX; // 鼠标指针的 X 坐标
var y = event.clientY; // 鼠标指针的 Y 坐标
// 显示鼠标的实时位置
document.getElementById('mousePosition').textContent = '鼠标位置:' + x + ', ' + y;
});
</script>
</body>
</html>- 在这个示例中,随着鼠标在页面上的移动,
mousemove
事件不断触发,更新显示鼠标当前坐标的段落文本。
-
mouseover
: 鼠标移到元素上方时触发。mouseover
事件在鼠标指针移动到一个元素上方时触发,它不仅响应该元素,还响应其子元素。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<html lang="en">
<head>
<meta charset="UTF-8">
<title>mouseover Event Example</title>
</head>
<body>
<!-- 创建一个会在鼠标移动到上方时变色的元素 -->
<div id="hoverDiv" style="width:200px; height:200px; background-color:#ddd;">
移动鼠标到这个方框里面
</div>
<script>
// 为方框元素添加 mouseover 事件监听器
document.getElementById('hoverDiv').addEventListener('mouseover', function (event) {
event.target.style.backgroundColor = 'purple'; // 改变背景色
});
</script>
</body>
</html>- 在这个示例中,当鼠标移动到
div
元素上方时,mouseover
事件被触发,方框的背景颜色变为紫色。
-
mouseout
: 鼠标离开元素时触发。mouseout
事件在鼠标指针移出一个元素时触发,这通常用于清除mouseover
事件应用的效果。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<html lang="en">
<head>
<meta charset="UTF-8">
<title>mouseout Event Example</title>
</head>
<body>
<!-- 创建一个会在鼠标移出时恢复原色的元素 -->
<div id="hoverDiv" style="width:200px; height:200px; background-color:#ddd;">
移动鼠标到这个方框里面,然后移出
</div>
<script>
var hoverDiv = document.getElementById('hoverDiv');
// 为方框元素添加 mouseover 事件监听器
hoverDiv.addEventListener('mouseover', function (event) {
event.target.style.backgroundColor = 'purple'; // 改变背景色
});
// 为方框元素添加 mouseout 事件监听器
hoverDiv.addEventListener('mouseout', function (event) {
event.target.style.backgroundColor = '#ddd'; // 恢复原始背景色
});
</script>
</body>
</html>- 在这个示例中,当鼠标移出
div
元素时,mouseout
事件被触发,方框的背景颜色恢复到原来的灰色。
-
-
键盘事件
-
keydown
: 用户按下键盘按键时触发。keydown
事件在用户按下键盘上的任何键时触发,而且如果用户按住键不放,会重复触发。这个事件适用于需要在用户开始按键时立刻响应的情况。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<html lang="en">
<head>
<meta charset="UTF-8">
<title>keydown Event Example</title>
</head>
<body>
<p>按下任意键以改变文本颜色。</p>
<input type="text" id="inputField" placeholder="在这里输入文字">
<script>
// 获取输入框元素
var input = document.getElementById('inputField');
// 为输入框添加 keydown 事件监听器
input.addEventListener('keydown', function () {
input.style.color = 'red'; // 当按键时改变文本颜色为红色
});
</script>
</body>
</html>- 在这个示例中,当用户开始在输入框中输入时,文本颜色会立即变为红色。
-
keypress
: 用户按下并释放键盘按键时触发(已废弃,不建议使用)。keypress
事件在用户按下能够产生字符的键时触发,例如字母、数字和符号键。请注意,某些浏览器已经不推荐使用keypress
事件,并可能在未来的标准中废弃。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<html lang="en">
<head>
<meta charset="UTF-8">
<title>keypress Event Example</title>
</head>
<body>
<p>在输入框中输入字符以听到声音。</p>
<input type="text" id="inputField" placeholder="在这里输入文字">
<script>
// 获取输入框元素
var input = document.getElementById('inputField');
// 为输入框添加 keypress 事件监听器
input.addEventListener('keypress', function () {
// 模拟按键声音
console.log('按键声音'); // 在实际应用中,这里可以播放声音
});
</script>
</body>
</html>- 在这个示例中,每当用户在输入框中按下一个产生字符的键时,控制台会打印出 “按键声音”。这里的
console.log
用于模拟实际的声音播放。
-
keyup
: 用户释放键盘按键时触发。keyup
事件在用户释放键盘上的键时触发。这个事件适用于需要在用户完成按键动作后响应的情况。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<html lang="en">
<head>
<meta charset="UTF-8">
<title>keyup Event Example</title>
</head>
<body>
<p>按下任意键改变文本颜色,释放后恢复文本颜色。</p>
<input type="text" id="inputField" placeholder="在这里输入文字并观察效果">
<script>
// 获取输入框元素
var input = document.getElementById('inputField');
// 为输入框添加 keydown 事件监听器
input.addEventListener('keydown', function () {
// 当按下键时改变文本颜色为红色
input.style.color = 'red';
});
// 为输入框添加 keyup 事件监听器
input.addEventListener('keyup', function () {
// 当释放按键时恢复文本颜色为黑色
input.style.color = 'black';
});
</script>
</body>
</html>- 在这个示例中,当用户按下一个键时,输入框内的文本颜色会变成红色;当您释放这个键时,颜色会恢复成黑色。
-
-
表单事件
-
submit
: 用户提交表单时触发。-
submit
事件在表单提交时触发。通常用于在表单数据发送到服务器之前进行验证。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<html lang="en">
<head>
<meta charset="UTF-8">
<title>submit Event Example</title>
</head>
<body>
<form id="form">
<label for="username">用户名:</label>
<input type="text" id="username" name="username" required><br>
<input type="submit" value="提交"><br>
</form>
<script>
// 获取表单元素
var form = document.getElementById('form');
// 为表单添加 submit 事件监听器
form.addEventListener('submit', function (event) {
alert('表单已提交!');
// 防止表单实际提交
event.preventDefault();
});
</script>
</body>
</html> -
在这个示例中,用户点击提交按钮时,会出现一个警告框通知用户表单已提交,然后通过
event.preventDefault()
阻止表单的实际提交,以便在客户端进行进一步的处理。
-
-
change
: 表单元素的值发生变化时触发。change
事件在表单元素的值发生变化时触发,并且当元素失去焦点时才会触发。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<html lang="en">
<head>
<meta charset="UTF-8">
<title>change Event Example</title>
</head>
<body>
<label for="select">选择你喜欢的颜色:</label>
<select id="select">
<option value="red">红色</option>
<option value="green">绿色</option>
<option value="blue">蓝色</option>
</select>
<script>
// 获取下拉菜单元素
var select = document.getElementById('select');
// 为下拉菜单添加 change 事件监听器
select.addEventListener('change', function () {
alert('你的选择是: ' + select.value);
});
</script>
</body>
</html>- 在这个示例中,当用户从下拉菜单中选择一个不同的选项并且下拉菜单失去焦点时,将触发
change
事件,并弹出一个警告框显示用户选择的值。
-
input
: 用户输入数据到<input>
,<textarea>
等元素时触发。input
事件每当<input>
、<select>
或<textarea>
元素的值改变时就会立即触发,不需要失去焦点。这使得它非常适合实时的输入处理,如即时搜索或验证。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<html lang="en">
<head>
<meta charset="UTF-8">
<title>input Event Example</title>
</head>
<body>
<label for="textfield">输入文本以进行实时显示:</label>
<input type="text" id="textfield">
<p id="output">在这里将会显示您输入的内容</p>
<script>
// 获取文本字段和输出元素
var textfield = document.getElementById('textfield');
var output = document.getElementById('output');
// 为文本字段添加 input 事件监听器
textfield.addEventListener('input', function () {
// 显示输入内容
output.textContent = '您输入的内容: ' + textfield.value;
});
</script>
</body>
</html>- 在这个示例中,每当用户在输入框中输入内容时,
input
事件就会触发,并且页面上的<p>
元素会实时更新显示用户输入的内容。
-
-
触摸事件
-
touchstart
: 用户触摸屏幕时触发。touchstart
事件在用户开始触摸屏幕元素时触发。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<html lang="en">
<head>
<meta charset="UTF-8">
<title>touchstart Event Example</title>
</head>
<body>
<div id="toucharea" style="width: 300px; height: 100px; background-color: #ccc;">
触摸这里
</div>
<script>
// 获取触摸区域元素
var toucharea = document.getElementById('toucharea');
// 为触摸区域添加 touchstart 事件监听器
toucharea.addEventListener('touchstart', function () {
alert('开始触摸!');
});
</script>
</body>
</html>- 在这个示例中,用户一旦触摸到指定的
div
元素,就会立即触发touchstart
事件,弹出提示框。
-
touchmove
: 用户在屏幕上滑动时触发。touchmove
事件在用户触摸屏幕后移动手指时触发。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<html lang="en">
<head>
<meta charset="UTF-8">
<title>touchmove Event Example</title>
</head>
<body>
<div id="toucharea" style="width: 300px; height: 100px; background-color: #ccc;">
在这里移动你的手指
</div>
<script>
// 获取触摸区域元素
var toucharea = document.getElementById('toucharea');
// 为触摸区域添加 touchmove 事件监听器
toucharea.addEventListener('touchmove', function (event) {
// 防止默认的滚动事件发生
event.preventDefault();
alert('移动中!');
}, { passive: false });
</script>
</body>
</html>- 在这个示例中,用户在
div
元素内移动手指会触发touchmove
事件,弹出提示框,并通过event.preventDefault()
阻止默认的滚动事件。 - 请注意,由于实际设备的触摸行为可能会引起页面的滚动等默认行为,因此在使用
touchmove
事件的时候通常会配合event.preventDefault()
来防止这些默认行为。此外,在移动设备上的浏览器中测试这些事件比在桌面浏览器上更为合适,因为桌面浏览器可能不支持触摸事件或者有不同的行为。
-
touchend
: 用户停止触摸屏幕时触发。touchend
事件在用户停止触摸屏幕时触发。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<html lang="en">
<head>
<meta charset="UTF-8">
<title>touchend Event Example</title>
</head>
<body>
<div id="toucharea" style="width: 300px; height: 100px; background-color: #ccc;">
释放你的手指
</div>
<script>
// 获取触摸区域元素
var toucharea = document.getElementById('toucharea');
// 为触摸区域添加 touchend 事件监听器
toucharea.addEventListener('touchend', function () {
alert('停止触摸!');
});
</script>
</body>
</html>- 在此示例中,当用户抬起手指停止触摸
div
元素时,会触发touchend
事件,弹出提示框。
-
选项卡
-
简介
DOM 选项卡(Tab)是一种常见的交互元素,可以让用户在不同的视图或内容区域之间切换,而不需要刷新页面。下面是一个简单的选项卡实现示例,使用了 HTML、CSS 和 JavaScript。
-
示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
<html>
<head>
<style>
/* 样式设置 */
.tab {
overflow: hidden;
border: 1px solid #ccc;
background-color: #f1f1f1;
}
.tab button {
background-color: inherit;
float: left;
border: none;
outline: none;
cursor: pointer;
padding: 14px 16px;
transition: 0.3s;
font-size: 17px;
}
.tab button:hover {
background-color: #ddd;
}
.tab button.active {
background-color: #ccc;
}
.tabcontent {
display: none;
padding: 6px 12px;
border: 1px solid #ccc;
border-top: none;
}
/* 当窗口宽度小于 600px 时,改变按钮的布局 */
@media screen and (max-width: 600px) {
.tab button {
float: none;
width: 100%;
text-align: left;
}
}
</style>
</head>
<body>
<div class="tab">
<button class="tablinks" onclick="openTab(event, 'London')">伦敦</button>
<button class="tablinks" onclick="openTab(event, 'Paris')">巴黎</button>
<button class="tablinks" onclick="openTab(event, 'Tokyo')">东京</button>
</div>
<div id="London" class="tabcontent">
<h3>伦敦</h3>
<p>伦敦是英国的首都,是一个古老而现代的城市。</p>
</div>
<div id="Paris" class="tabcontent">
<h3>巴黎</h3>
<p>巴黎是法国的首都,被称为“光之城”。</p>
</div>
<div id="Tokyo" class="tabcontent">
<h3>东京</h3>
<p>东京是日本的首都,是世界上最大的都市圈之一。</p>
</div>
<script>
function openTab(evt, cityName) {
// 声明所有变量
var i, tabcontent, tablinks;
// 获取所有的tabcontent元素并隐藏它们
tabcontent = document.getElementsByClassName("tabcontent");
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "none";
}
// 获取所有的tablinks元素并移除"active"类
tablinks = document.getElementsByClassName("tablinks");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].className = tablinks[i].className.replace(" active", "");
}
// 显示当前标签页的内容,并添加"active"类到按钮上
document.getElementById(cityName).style.display = "block";
evt.currentTarget.className += " active";
}
</script>
</body>
</html>在这个示例中:
- 每个选项卡按钮
<button>
都有一个 onclick 事件处理器,当点击时调用openTab
函数,并传入当前事件对象和要显示的选项卡内容的 ID。 openTab
函数首先隐藏所有的选项卡内容(.tabcontent
),然后移除所有选项卡按钮的active
类,最后显示被选中的选项卡内容并给对应的按钮添加active
类来高亮显示。- CSS 用于设置选项卡的基本样式,例如隐藏内容、鼠标悬停效果和媒体查询等。
- 每个选项卡按钮
定时器
-
简介
在 JavaScript 中,DOM 定时器允许你以指定的时间间隔执行代码。这通常通过两个主要的方法实现:
setTimeout
和setInterval
。 -
setTimeout
setTimeout
函数用于在指定的毫秒数后执行一个函数或指定的一段代码。setTimeout
是窗口对象的方法,它返回一个定时器标识符,这个标识符可以用于取消定时器。- 下面是一个使用
setTimeout
的例子,在3秒后页面会弹出一个警告框:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<html lang="en">
<head>
<meta charset="UTF-8">
<title>setTimeout Example</title>
<script>
function delayedAlert() {
// 设置一个定时器,在3秒后执行
setTimeout(function () {
alert("这条消息是3秒后弹出的!");
}, 3000);
}
</script>
</head>
<body onload="delayedAlert();">
<h1>setTimeout 示例</h1>
<p>页面加载后,将等待3秒钟,然后显示一个弹窗。</p>
</body>
</html> - 在这个例子中,当页面加载 (
onload
) 时,会调用delayedAlert
函数。delayedAlert
函数内部使用setTimeout
设置了一个定时器,该定时器在3000毫秒(即3秒)后触发匿名函数,该匿名函数通过alert
来显示一条消息。 setTimeout
可以让你延迟执行某个操作,而不会阻塞后续的 JavaScript 代码的执行,因为 JavaScript 是单线程执行的,使用定时器可以安排任务在未来的某个时间点执行。
-
setInterval
setInterval
函数用于在指定的每隔一段时间重复执行一段代码。- 以下是一个使用
setInterval
的例子,该例子会每隔1秒更新页面上的当前时间。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<html lang="en">
<head>
<meta charset="UTF-8">
<title>setInterval Example</title>
<script>
// 定义函数以更新时间
function updateTime() {
var currentTime = new Date();
document.getElementById('clock').innerHTML = currentTime.toLocaleTimeString();
}
// 页面加载时启动定时器
window.onload = function () {
// 每1000毫秒(即1秒)调用一次updateTime函数
setInterval(updateTime, 1000);
};
</script>
</head>
<body>
<h1>实时时钟示例</h1>
<p>当前时间:<span id="clock"></span></p>
</body>
</html> - 在这个例子中:
- 当页面加载时
window.onload
事件触发,这时会设置一个定时器,它每隔1秒就会调用一次updateTime
函数。 updateTime
函数获取当前的时间,并且更新页面中id
为clock
的元素的内容。document.getElementById('clock').innerHTML
替换了所选元素的 HTML 内容,这样用户就能在页面上看到每秒钟更新一次的实时时间。
- 当页面加载时
setInterval
是用来创建重复定时器的,这意味着它会无限次地执行代码,直到clearInterval
被调用或窗口被关闭。这使得setInterval
非常适合那些需要定期执行的任务,比如实时更新UI。
-
clearTimeout 和 clearInterval
-
简介
clearTimeout
和clearInterval
函数分别用于取消由setTimeout
和setInterval
设置的定时器。以下是如何使用这些函数的例子。- 这两个方法为开发者提供了控制定时器行为的灵活性,尤其是当定时器的持续运行可能不再需要时,或者因为某些条件改变(如用户的交互)而必须停止定时器。
-
clearTimeout
假设你设置了一个
setTimeout
定时器,希望在5秒后执行某个操作,但在定时器执行之前,用户进行了某个操作(比如点击了一个按钮),你想要取消这个定时器。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<html lang="en">
<head>
<meta charset="UTF-8">
<title>clearTimeout Example</title>
<script>
var timer;
function setTimer() {
timer = setTimeout(function () {
alert("这条消息会在5秒后显示,除非被取消。");
}, 5000);
alert("定时器已设置。");
}
function cancelTimer() {
clearTimeout(timer);
alert("定时器已取消。");
}
</script>
</head>
<body>
<button onclick="setTimer()">设置定时器</button>
<button onclick="cancelTimer()">取消定时器</button>
</body>
</html>在这个例子中,当用户点击“设置定时器”按钮时,会设置一个5秒后运行的定时器。如果在这5秒内用户点击了“取消定时器”按钮,
clearTimeout
将取消之前设置的定时器,防止它执行。 -
clearInterval
现在,假设你用
setInterval
设置了一个每2秒更新一次时间的定时器,但你希望用户可以随时停止这个定时更新。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<html lang="en">
<head>
<meta charset="UTF-8">
<title>clearInterval Example</title>
<script>
var interval;
function startTime() {
interval = setInterval(updateTime, 2000);
alert("时间每2秒更新一次。");
}
function stopTime() {
clearInterval(interval);
alert("时间更新已停止。");
}
function updateTime() {
document.getElementById('clock').innerHTML = new Date().toLocaleTimeString();
}
</script>
</head>
<body>
<button onclick="startTime()">开始时间更新</button>
<button onclick="stopTime()">停止时间更新</button>
<p>当前时间:<span id="clock"></span></p>
</body>
</html>在这个例子中,用户点击“开始时间更新”按钮开始定时器,页面上的时间就会每2秒刷新一次。点击“停止时间更新”按钮会调用
clearInterval
方法,这会停止setInterval
定时器的执行,时间更新停止。
-
window
-
简介
在 Web 浏览器中,
window
对象表示一个打开的浏览器窗口或框架,并且是所有全局 JavaScript 对象、函数和变量的最顶层对象。window
对象为开发者提供了控制浏览器窗口的接口,并且可以访问诸如文档对象模型(DOM)、浏览器历史、屏幕大小、视口位置等属性。 -
属性
window.document
: 指向加载在窗口中的文档的Document
对象。document.title
: 获取或设置文档的标题。document.URL
: 返回文档的完整URL。document.write(html)
: 向文档写入HTML表达式或JavaScript代码片段。
window.location
: 提供了当前窗口的位置信息,并允许重定向到新的URL。window.history
: 提供了浏览历史的操作方法,如前进和后退。window.screen
: 包含关于用户屏幕的信息,如其分辨率。window.navigator
: 提供了关于浏览器的信息,包括版本和操作系统。window.innerWidth
/window.innerHeight
: 分别表示窗口的内部宽度和高度(不包括工具栏和滚动条)。window.outerWidth
/window.outerHeight
: 分别表示窗口的外部宽度和高度(包括工具栏和滚动条)。window.pageXOffset
/window.pageYOffset
: 提供了窗口的水平和垂直滚动偏移量。window.localStorage
: 提供了本地存储功能,允许网站存储键值对数据。window.sessionStorage
: 提供了会话存储功能,类似于本地存储,但是数据在窗口或标签页关闭后会消失。window.console
: 提供了访问浏览器控制台的功能,通常用于调试。window.performance
: 提供了当前页面与性能相关的信息和操作方法。window.frames
: 包含窗口中所有框架(<iframe>
元素)的数组。window.self
: 返回其自身的引用,等同于window
。window.parent
: 返回当前窗口的父窗口。window.top
: 返回当前上下文中最顶层的窗口。window.name
: 可以获取或设置窗口的名称。window.status
: 可以设置读取窗口左下角的状态栏的文本(但现代浏览器一般不显示状态栏文本)。window.opener
: 如果当前窗口由另一个窗口打开,则该属性是一个对创建当前窗口的窗口的引用。
-
方法
alert(message)
:显示带有一条消息和一个确认按钮的警告框。confirm(message)
:显示带有一条消息、确认按钮和取消按钮的对话框,用于确认或取消操作。prompt(message, default)
:显示带有一条消息、文本输入框和确认按钮的对话框,用于输入信息。open(url, target, features)
:打开一个新的浏览器窗口或标签页,可以指定URL、目标窗口和一些特性。close()
:关闭当前窗口。setTimeout(function, delay)
:在指定的延迟时间后执行一次函数。setInterval(function, delay)
:每隔指定的时间间隔执行一次函数。clearTimeout(timeoutID)
:取消之前通过setTimeout
方法设置的延迟执行。clearInterval(intervalID)
:取消之前通过setInterval
方法设置的循环执行。focus()
:将焦点设置到当前窗口。blur()
:将焦点从当前窗口移除。scrollTo(x, y)
:将窗口滚动到指定的坐标位置。scrollBy(x, y)
:将窗口滚动指定的偏移量。resizeTo(width, height)
:将窗口调整到指定的宽度和高度。resizeBy(width, height)
:将窗口调整指定的增量宽度和高度。
-
事件
load
:当窗口和所有资源(如图像、样式表)都加载完成后触发。可以用来执行一些初始化操作。unload
:当窗口即将关闭或导航离开当前页面时触发。可以用来执行一些清理操作。beforeunload
:当窗口即将关闭或导航离开当前页面时触发,但在unload
事件之前。可以用来提示用户是否离开当前页面。resize
:当窗口大小改变时触发。可以用来调整页面布局或响应窗口大小变化。scroll
:当窗口滚动时触发。可以用来实现滚动事件的处理逻辑。focus
:当窗口或窗口中的元素获得焦点时触发。blur
:当窗口或窗口中的元素失去焦点时触发。keydown
、keyup
、keypress
:当用户按下或释放键盘上的键时触发。click
、dblclick
:当用户单击或双击鼠标时触发。mousedown
、mouseup
、mousemove
:当用户按下、释放或移动鼠标时触发。contextmenu
:当用户右键单击鼠标时触发。error
:当加载文档或资源时发生错误时触发。- 示例
1
2
3window.addEventListener('load', function () {
// 页面完全加载完成后,执行的代码
});
-
简单示例
假设您想要打开一个新的窗口,并在一段时间后自动关闭它,可以使用下面的代码:
1
2
3
4
5
6
7
8
9// 打开一个新窗口
var myWindow = window.open("", "MsgWindow", "width=200, height=100");
// 在新窗口中写入一些HTML内容
myWindow.document.write("<p>这是一个新窗口。</p>");
// 设置3秒后关闭新窗口的定时器
setTimeout(function () {
myWindow.close();
}, 3000);window
对象是 Web API 的核心,通过它的不同属性和方法,可以实现与浏览器窗口的各种交互。
获取样式
-
使用
style
属性element.style
: 这将返回一个对象,该对象表示元素的style
属性。这种方法只能访问到内联样式(即直接在元素的style
属性中定义的样式)。- 例如,如果你有如下HTML元素:
1
<div id="myDiv" style="color: blue; font-size: 14px;">Hello World!</div>
- 你可以这样使用 JavaScript 来获取样式:
1
2
3var myDiv = document.getElementById('myDiv');
var color = myDiv.style.color; // 返回 "blue"
var fontSize = myDiv.style.fontSize; // 返回 "14px" - 值得注意的是,如果样式是通过样式表或者外部CSS文件应用的,那么
element.style
对象将不会包含这些样式。
-
使用
window.getComputedStyle()
方法window.getComputedStyle(element)
: 这个方法会返回一个包含元素的所有计算后样式的CSSStyleDeclaration
对象,这包括了那些通过样式表应用的样式。- 例如:
1
2
3
4var myDiv = document.getElementById('myDiv');
var style = window.getComputedStyle(myDiv);
var color = style.color; // 返回计算后的颜色值,例如 "rgb(0, 0, 255)"
var fontSize = style.fontSize; // 返回计算后的字号,例如 "14px" getComputedStyle()
方法可以用来获取任何应用到元素上的样式信息,包括内联样式、嵌入样式和外部样式表。这是获取计算后样式(实际在页面上显示的样式)最准确的方法。
练习
- **选项卡:**要求鼠标放上去就显示对应的版块,隐藏其他版块
- **秒表效果:**添加控制按钮,开始、停止、重置
- **飘舞的小球:**显示一个小球,在窗口范围内飘动,遇到边界就反向
查找元素(二)
-
父元素
parentNode
: 返回指定节点的父节点。parentElement
: 返回指定节点的父元素节点(与parentNode
类似,但是只返回元素节点)。
-
子元素
childNodes
: 返回包含指定元素所有子节点的NodeList。children
: 返回包含指定元素所有子元素节点的HTMLCollection。firstChild
: 返回指定节点的第一个子节点。firstElementChild
: 返回指定元素的第一个子元素节点。lastChild
: 返回指定节点的最后一个子节点。lastElementChild
: 返回指定元素的最后一个子元素节点。
-
同胞元素
nextSibling
: 返回指定节点紧随的同胞节点。nextElementSibling
: 返回指定元素紧随的同胞元素。previousSibling
: 返回指定节点之前的同胞节点。previousElementSibling
: 返回指定元素之前的同胞元素。
-
例子
-
假设有如下HTML结构:
1
2
3
4
5<div id="parent">
<div id="previousSibling"></div>
<div id="target">目标元素</div>
<div id="nextSibling"></div>
</div> -
访问父元素:
1
2var target = document.getElementById('target');
var parent = target.parentElement; // 或 target.parentNode -
访问子元素:
1
2
3
4var parent = document.getElementById('parent');
var firstChild = parent.firstElementChild; // 或 parent.firstChild
var lastChild = parent.lastElementChild; // 或 parent.lastChild
var allChildren = parent.children; // 或 parent.childNodes -
访问同胞元素:
1
2
3var target = document.getElementById('target');
var nextSibling = target.nextElementSibling; // 或 target.nextSibling
var previousSibling = target.previousElementSibling; // 或 target.previousSibling
-
-
注意事项
childNodes
包含了元素节点之外的其他类型的节点,如文本节点和注释节点,而children
、firstElementChild
、lastElementChild
、nextElementSibling
和previousElementSibling
只关联元素节点。如果你只关心元素节点而非其他类型的节点,应该使用带有 “Element” 的属性。
创建与删除
-
创建元素
createElement(tagName)
: 创建一个新的元素节点。它接受一个标签名作为参数。createTextNode(text)
: 创建一个新的文本节点。这用于将文本内容添加到元素中。createDocumentFragment()
: 创建一个新的空文档片段,它不是真正的DOM树的一部分,在将多个子节点插入DOM树时可以提供性能上的优势。
-
添加元素
appendChild(child)
: 将一个节点添加到指定父节点的子节点列表的末尾。insertBefore(newNode, referenceNode)
: 在指定的参考节点前插入新的子节点。
-
删除元素
removeChild(child)
: 从DOM中删除一个子节点。它返回被删除的节点。remove()
: 一个较新的方法,允许你直接从它所属的节点上调用,删除自身。
-
替换元素
replaceChild(newChild, oldChild)
: 用另一个节点替换当前节点的一个子节点。
-
例子
- 创建一个新元素
1
2
3
4
5
6// 创建一个新的 <div> 元素节点
var newDiv = document.createElement('div');
// 创建一个新的文本节点
var newContent = document.createTextNode('Hi there and greetings!');
// 将文本添加到 <div> 中
newDiv.appendChild(newContent); - 向文档添加新创建的元素
1
2
3// 假设我们已有一个 ID 为 "myDiv" 的 <div> 元素
var currentDiv = document.getElementById('myDiv');
document.body.insertBefore(newDiv, currentDiv); - 删除一个元素
1
2
3
4
5// 假设我们的 newDiv 已经添加到了页面上
newDiv.remove(); // 如果支持.remove()方法
// 或者
var parentDiv = newDiv.parentNode;
parentDiv.removeChild(newDiv); // 对于不支持 .remove() 方法的情况 - 替换一个元素
1
2
3// 假设我们已有 oldDiv 需要被 newDiv 替换
var oldDiv = document.getElementById('oldDiv');
oldDiv.parentNode.replaceChild(newDiv, oldDiv); - 注意事项
执行DOM创建和删除操作时,需要考虑到这些操作可能对页面性能有显著影响,特别是在大量元素和频繁操作时。合理使用createDocumentFragment
可以帮助减少页面重绘和回流,从而提高性能。
- 创建一个新元素
事件冒泡
-
简介
- 事件冒泡是指事件从最具体的元素(文档树中最深的那个节点)开始发生,然后逐级向上传播到较为不具体的节点(文档)。这是事件传播的一种机制。
- 例如,如果你有一个按钮元素(
<button>
)包含在一个段落(<p>
)元素中,它们又都包含在一个文档(<body>
)元素中,那么:- 当按钮被点击时,首先在按钮上触发点击事件。
- 接着事件会向上冒泡到
<p>
元素,在那里也可以捕获和处理这个事件。 - 最后事件继续冒泡到
<body>
元素和任何其他包含元素。
- 在事件冒泡过程中,可以在任何级别上响应事件(如果有事件监听器被添加)。这种机制允许你在一个高级别上处理多个元素的事件,这称为事件委托。事件委托是一种常用的事件处理模式,它利用了事件冒泡的特性来减少需要添加到DOM中的事件处理器的数量。
- 如果你不希望事件继续冒泡,可以使用事件对象的
stopPropagation()
方法来停止冒泡过程。例如:1
2
3
4element.addEventListener('click', function (event) {
event.stopPropagation();
// ...你的事件处理逻辑...
}); - 在上面的代码中,
event.stopPropagation()
会阻止事件进一步冒泡,因此任何包含元素上的点击事件处理器都不会被触发。 - 有时候,你可能会听到“捕获阶段”(capturing phase)这个术语,它是事件传播的另一个阶段,与冒泡相反,事件从最不具体的节点开始,然后逐级向下传播到最具体的节点。你可以在添加事件监听器时选择是在捕获阶段处理事件还是在冒泡阶段处理事件。默认情况下,事件监听器是在冒泡阶段执行的,但是你可以将
addEventListener
的第三个参数设置为true
来指定在捕获阶段触发事件处理函数:1
2
3element.addEventListener('click', function (event) {
// ...你的事件处理逻辑...
}, true); // true 表示在捕获阶段处理事件 - 注意,并非所有事件都会冒泡,有些事件是不冒泡的,例如
focus
、blur
和load
事件。对于这些事件,stopPropagation()
方法不会产生冒泡阶段中的任何效果,因为它们根本就没有冒泡过程。
-
示例
- 假设我们有以下HTML结构:
1
2
3
4
5<div id="grandparent">
<div id="parent">
<button id="child">Click Me!</button>
</div>
</div> - 在这个结构中,我们有一个按钮(
<button>
),它被包含在一个父<div>
内,该父<div>
又被包含在一个祖父<div>
内。我们现在为这三个元素添加事件监听器,以观察冒泡过程:当用户点击按钮时,以下事件将会发生:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17// 获取元素
var grandparent = document.getElementById('grandparent');
var parent = document.getElementById('parent');
var child = document.getElementById('child');
// 添加事件监听器
grandparent.addEventListener('click', function () {
console.log('Grandparent click');
});
parent.addEventListener('click', function () {
console.log('Parent click');
});
child.addEventListener('click', function () {
console.log('Child click');
});- 首先,在
<button>
(child)上触发点击事件。 - 控制台将输出“Child click”。
- 然后,点击事件开始冒泡到父元素(parent),这个元素上的监听器被触发。
- 控制台将输出“Parent click”。
- 最后,事件继续冒泡到祖父元素(grandparent),它的监听器也被触发。
- 控制台将输出“Grandparent click”。
- 首先,在
- 因此,如果你在页面上点击“Click Me!”按钮,控制台最终将显示:
1
2
3Child click
Parent click
Grandparent click - 这显示了事件冒泡的过程。事件从最具体的元素开始,并向上传播到更不具体的元素,除非中途被取消。
- 如果你想阻止这个冒泡过程,可以在事件处理函数中使用
event.stopPropagation()
。例如:1
2
3
4child.addEventListener('click', function (event) {
console.log('Child click');
event.stopPropagation(); // 阻止事件继续冒泡
}); - 如果你这样做,当用户点击按钮时,祖父和父元素上绑定的事件监听器不会被触发,只有“Child click”会被输出到控制台。
- 假设我们有以下HTML结构:
事件绑定
-
简介
事件绑定是指将事件监听器(即回调函数)与特定的DOM元素关联起来,以便当特定事件发生时能够执行一些代码。
-
基本的事件绑定
-
使用addEventListener方法
addEventListener
是推荐使用的方法来绑定事件,因为它允许你为同一个事件添加多个监听器,并且它也提供了使用事件捕获的选项。1
2
3
4
5
6
7
8// 获取元素
var button = document.getElementById('myButton');
// 事件绑定
button.addEventListener('click', function (event) {
// 处理点击事件
console.log('Button was clicked!');
}); -
使用on-event属性
- 另一种绑定事件的方式是使用 HTML 元素的
on-event
属性,如onclick
、onmouseover
等。这些属性可以在HTML 标签中直接设置,也可以在 JavaScript 中设置。 - 在 HTML 中设置
1
2
3
4
5
6
7<button id="myButton" onclick="handleClick()">Click me</button>
<script>
function handleClick() {
console.log('Button was clicked!');
}
</script> - 在 JavaScript 中设置
1
2
3
4
5
6
7
8// 获取元素
var button = document.getElementById('myButton');
// 事件绑定
button.onclick = function (event) {
// 处理点击事件
console.log('Button was clicked!');
};
- 另一种绑定事件的方式是使用 HTML 元素的
-
-
移除事件监听器
你也可以使用
removeEventListener
方法来移除之前通过addEventListener
方法添加的事件监听器。这对于清理和避免内存泄漏特别有用。1
2
3
4
5
6
7
8
9
10// 事件监听器函数
function clickHandler(event) {
console.log('Button was clicked!');
}
// 绑定事件监听器
button.addEventListener('click', clickHandler);
// ...之后的某个时间点,移除事件监听器
button.removeEventListener('click', clickHandler);注意,使用
removeEventListener
时,你必须传入与addEventListener
时相同的回调函数引用。如果你传入一个不同的函数,那么原先的事件监听器将不会被移除。 -
事件监听器的第三个参数
addEventListener
方法的第三个参数可以是一个布尔值或者是一个选项对象。如果是布尔值,true
表示监听器将在捕获阶段触发,false
表示监听器将在冒泡阶段(默认)触发。1
2button.addEventListener('click', clickHandler, false); // 冒泡阶段触发(默认)
button.addEventListener('click', clickHandler, true); // 捕获阶段触发如果是一个选项对象,你可以指定更多的选项:
1
2
3
4
5button.addEventListener('click', clickHandler, {
capture: false, // 相当于之前的布尔值
once: true, // 事件只触发一次
passive: true // 表明事件处理程序不会调用 preventDefault()
});
事件源元素
-
简介
在 DOM 事件处理中,事件源元素是指触发事件的具体元素。当你给某个元素添加事件监听器,并且该事件被触发时,你可以通过事件对象的
target
属性来访问这个事件源元素。 -
示例
- 举例来说,你有如下的HTML代码:
1
<button id="myButton">Click me</button>
- 并且你用 JavaScript 给这个按钮添加了点击事件的监听器:
1
2
3
4document.getElementById('myButton').addEventListener('click', function (event) {
// event.target 就是触发点击事件的元素,即按钮本身
console.log('The event is triggered by:', event.target);
}); - 当这个按钮被点击时,事件监听器会被触发,输出相应的信息及事件源元素到控制台。
1
The event is triggered by: <button id="myButton">Click me</button>
- 事件对象还有一个
currentTarget
属性,通常与target
相同,但如果事件监听器在事件的捕获或冒泡阶段被触发,则currentTarget
将是事件到达的当前 DOM 元素,这通常是绑定监听器的那个元素。 - 以冒泡为例,如果有一个嵌套元素结构,并且父元素也有一个事件监听器:
1
2
3<div id="parent">
<button id="myButton">Click me</button>
</div>1
2
3
4
5
6
7// 给父元素添加点击事件监听器
document.getElementById('parent').addEventListener('click', function (event) {
// event.target 是触发点击事件的最具体的元素,即按钮
// event.currentTarget 是绑定了当前执行的事件监听器的元素,即父元素
console.log('Triggered by:', event.target);
console.log('Current target:', event.currentTarget);
}); - 当按钮被点击时,虽然事件源(
event.target
)是按钮,但在父元素的事件监听器中,event.currentTarget
将是父<div>
元素,因为那是当前正在处理事件的元素。 - 区分
target
和currentTarget
可以在处理复杂的事件委托时非常有用。
- 举例来说,你有如下的HTML代码:
点击位置
-
简介
- 要获取鼠标在 DOM 上点击的具体位置,你可以使用鼠标事件对象的属性。这些属性主要分为两类:相对于整个文档的位置,和相对于触发事件元素的位置。
- 以下是一些常用的属性:
pageX
和pageY
:这些属性提供了鼠标点击位置相对于整个文档的坐标。clientX
和clientY
:这些属性提供了鼠标点击位置相对于浏览器可视区域(viewport)的坐标。offsetX
和offsetY
:这些属性提供了鼠标点击位置相对于触发事件的元素的边界的坐标。
-
示例
- 例如,如果你想获取用户在一个按钮上点击的位置,你可以这样做:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19var button = document.getElementById('myButton');
button.addEventListener('click', function (event) {
// 获取相对于文档的位置
var pageClickX = event.pageX;
var pageClickY = event.pageY;
// 获取相对于浏览器窗口的位置
var clientClickX = event.clientX;
var clientClickY = event.clientY;
// 获取相对于按钮本身的位置
var offsetX = event.offsetX;
var offsetY = event.offsetY;
console.log('Page X/Y:', pageClickX, pageClickY);
console.log('Client X/Y:', clientClickX, clientClickY);
console.log('Offset X/Y:', offsetX, offsetY);
}); - 这段代码会在用户点击按钮时输出点击位置的三组坐标值。
- 请注意,
pageX
和pageY
在处理滚动时特别有用,因为它们考虑了页面可能已经滚动过的部分。而clientX
和clientY
则只是基于当前视窗的位置。offsetX
和offsetY
对于了解用户在特定元素上点击的精确位置非常有用,例如,如果你想在元素上实现一个绘图应用,用户的每次点击都需要精确位置。 - 在不同的开发情境中,这些属性可以用来执行各种任务,如在点击位置显示上下文菜单、实现拖放界面、绘图应用等。
- 例如,如果你想获取用户在一个按钮上点击的位置,你可以这样做:
拖拽元素
-
简介
- 在 Web 页面中实现拖拽功能,可以借助 HTML5 的拖放 API(Drag and Drop API)或通过 JavaScript 手动实现。
- 通过 JavaScript 手动实现:
mousedown
: 用户按下鼠标按键时触发mouseup
: 用户释放鼠标按键时触发mousemove
: 鼠标在元素上移动时触发
-
示例
下面是一个基本的 JavaScript 拖拽功能的实现示例:
- 首先是 HTML 元素,例如一个可拖拽的
div
:1
2
3<div id="draggable" style="width: 100px; height: 100px; background: red; position: absolute;">
拖拽我
</div> - 然后是 JavaScript 代码,用于添加拖拽逻辑:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29// 获取拖拽元素
var draggable = document.getElementById('draggable');
// 初始化变量
var offsetX = 0, offsetY = 0, drag = false;
// 鼠标按下事件
draggable.addEventListener('mousedown', function (e) {
// 开始拖拽
drag = true;
// 计算鼠标相对元素的位置
offsetX = e.clientX - draggable.getBoundingClientRect().left;
offsetY = e.clientY - draggable.getBoundingClientRect().top;
});
// 鼠标释放事件
document.addEventListener('mouseup', function () {
// 停止拖拽
drag = false;
});
// 鼠标移动事件
document.addEventListener('mousemove', function (e) {
if (drag) { // 只有在拖拽状态下才执行
// 计算元素的新位置
draggable.style.left = e.clientX - offsetX + 'px';
draggable.style.top = e.clientY - offsetY + 'px';
}
}); - 这段代码的工作原理如下:
- 当用户在元素上按下鼠标按钮时(
mousedown
事件),标记开始拖拽(drag = true
)并且计算鼠标指针位置与元素位置的偏移量。 - 当用户释放鼠标按钮时(
mouseup
事件,这里绑定在整个文档上以防止光标离开元素时失去功能),标记拖拽结束(drag = false
)。 - 当用户移动鼠标时(
mousemove
事件),如果处于拖拽状态,就根据当前鼠标位置和之前计算的偏移量,不断更新元素的位置。
- 当用户在元素上按下鼠标按钮时(
- 请注意,这个示例假设元素的
position
样式已设置为absolute
,这样才能通过left
和top
样式属性来控制元素位置。确保在实际使用时调整样式和逻辑,使其符合你的具体需求。 - 这是一个简化的拖拽实现,没有处理一些实际应用中可能遇到的复杂情况,比如边界检查(防止元素被拖出可视区域)、触摸屏支持或者与浏览器默认拖放行为的冲突等问题。对于更复杂的拖拽需求,可能需要更详细的代码来处理这些情况。
- 首先是 HTML 元素,例如一个可拖拽的
获取元素属性
-
getAttribute()
和setAttribute()
方法1
2
3
4var element = document.getElementById('myElement');
var attributeName = 'data-custom-attribute';
var attributeValue = element.getAttribute(attributeName); // 获取属性值
element.setAttribute(attributeName, 'new value'); // 设置新的属性值 -
直接访问属性
如果是标准的 HTML 属性,如
id
,src
,href
,value
等,可以直接通过元素对象访问并设置它们。1
2
3var element = document.getElementById('myElement');
var elementId = element.id; // 获取id属性
element.value = 'new value'; // 设置value属性 -
使用属性访问器
element.property
对于 HTML 元素的布尔属性,如
checked
,disabled
,selected
等,通常使用属性访问器直接设置和获取。1
2
3var checkbox = document.getElementById('myCheckbox');
var isChecked = checkbox.checked; // 获取checked属性
checkbox.disabled = true; // 设置disabled属性 -
dataset
属性对于自定义的
data-*
属性,可以通过dataset
属性来访问。1
2
3var element = document.getElementById('myElement');
var dataValue = element.dataset.myCustomData; // 获取data-my-custom-data属性
element.dataset.myCustomData = 'new value'; // 设置新的值 -
className
和classList
对于
class
属性,可以使用className
或者classList
API 来获取或修改元素的类。1
2
3
4var element = document.getElementById('myElement');
var classList = element.className; // 获取所有的类
element.classList.add('new-class'); // 添加一个新的类
element.classList.remove('existing-class'); // 移除一个已有的类 -
style
属性可以通过
style
属性来获取或设置元素的行内样式(即style
属性的值)。1
2
3var element = document.getElementById('myElement');
var currentStyle = element.style.backgroundColor; // 获取背景颜色
element.style.color = 'red'; // 设置文字颜色
DOM 键盘事件
-
简介
在 JavaScript 中,键盘事件通常被用来响应用户的键盘操作。主要有三种键盘事件:
keydown
:当用户按下键盘上的任意键时触发,如果按住不放,会重复触发该事件。keypress
:当用户按下键盘上的字符键时触发,如果按住不放,会重复触发该事件。注意,在最新的标准中keypress
事件已经被废弃,不建议使用。keyup
:当用户释放键盘上的键时触发。
-
示例
- 这些事件可以在全局范围内(通常是
window
对象)或特定元素上(如输入框等)监听。以下是一些使用这些事件的示例:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20// 监听全局的键盘按下事件
window.addEventListener('keydown', function (event) {
console.log('按下了键:', event.key);
console.log('按键的代码是:', event.code);
});
// 监听全局的键盘释放事件
window.addEventListener('keyup', function (event) {
console.log('释放了键:', event.key);
});
// 获取一个输入框元素
var inputElement = document.getElementById('myInput');
// 监听输入框的键盘按下事件
inputElement.addEventListener('keydown', function (event) {
if (event.key === 'Enter') { // 检查是否为“回车”键
console.log('在输入框中按了回车!');
}
}); - 在键盘事件对象中,有几个常用的属性提供了关于触发事件的键的信息:
key
:返回被按下的键的字符值,例如 ‘a’、‘1’ 或 ‘Enter’。code
:返回一个字符串,代表了被按下的键的物理位置的键码,例如 ‘KeyA’、‘Digit1’ 或 ‘Enter’,与键的字符值无关。keyCode
(已废弃):返回一个数字,代表了被按下的键的键码,例如 65 代表 ‘A’,但由于不同键盘布局和不同浏览器之间存在差异,不推荐使用。ctrlKey
、shiftKey
、altKey
、metaKey
:这些属性表明控制键是否被同时按下,它们是布尔值。
- 监听键盘事件时,你可能需要根据实际需求来决定在哪个元素上添加事件监听器以及如何处理事件。例如,在处理文本输入时,监听特定的输入框元素可能更有意义,而在处理快捷键时,可能需要在全局对象上监听。
- 这些事件可以在全局范围内(通常是
禁用右键
-
简介
在网页上禁用右键通常是通过监听
contextmenu
事件实现的,该事件在用户尝试打开上下文菜单(通常是通过右键点击)时触发。可以在全局范围内或特定元素上阻止这一默认行为。 -
示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Disable Right Click</title>
<script>
// 当文档加载完成时
window.onload = function () {
// 监听contextmenu事件
document.addEventListener('contextmenu', function (event) {
// 阻止默认的上下文菜单
event.preventDefault();
});
};
</script>
</head>
<body>
<p>右键菜单在此页面上被禁用。</p>
</body>
</html>
禁止跳转
-
简介
在网页中禁止某些链接跳转通常是通过阻止链接的默认行为来实现的。当用户点击链接时,会触发一个名为
click
的事件,通过监听这个事件并调用事件对象的preventDefault
方法,可以阻止链接默认的跳转行为。 -
示例
- 以下是一个示例,展示如何为具有特定类名的所有链接添加事件监听器来阻止它们跳转:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Disable Link Navigation</title>
<script>
window.onload = function () {
// 获取所有类名为 'no-link' 的链接
var links = document.querySelectorAll('a.no-link');
// 为每个链接添加点击事件监听器
links.forEach(function (link) {
link.addEventListener('click', function (event) {
// 阻止链接的默认跳转行为
event.preventDefault();
});
});
};
</script>
</head>
<body>
<a href="https://www.example.com" class="no-link">This link won't navigate.</a><br>
<a href="https://www.example.com">This link will navigate as normal.</a>
</body>
</html> - 在这个例子中,我们添加了一个
click
事件监听器到所有具有no-link
类的<a>
元素上。通过调用preventDefault
方法,我们取消了这些链接的默认导航行为。 - 请注意,尽管可以通过这种方式阻止链接默认的行为,但这样做可能会对用户体验产生影响,特别是当用户期望链接能够正常工作时。因此,你应该考虑这样做的理由,并确保用户能够理解为何链接不可点击。
- 以下是一个示例,展示如何为具有特定类名的所有链接添加事件监听器来阻止它们跳转:
各种弹出框
-
alert
一个简单的对话框,显示一条消息和一个确定按钮。用户必须点击确定才能继续操作。
1
alert('这是一个警告框。');
-
confirm
一个对话框,显示一条消息以及确定和取消按钮。它返回一个布尔值,指示用户是否点击了确定(
true
)或取消(false
)。1
2
3
4
5
6
7if (confirm('你确定要执行这个操作吗?')) {
// 如果点击了“确定”,则执行这里的代码
console.log('用户点击了确定。');
} else {
// 如果点击了“取消”,则执行这里的代码
console.log('用户点击了取消。');
} -
prompt
一个对话框,除了显示消息和提供确定取消按钮外,还提供一个文本输入框供用户输入。点击确定后,它会返回输入框内的值。如果用户点击取消或关闭对话框,它通常返回
null
。1
2
3
4
5
6var userName = prompt('请输入你的名字:', '匿名用户');
if (userName) {
console.log('用户的名字是:' + userName);
} else {
console.log('用户没有输入名字。');
}
BOM 操作?
-
简介
- BOM 是浏览器对象模型(Browser Object Model)的缩写,它不是正式的标准,但是一个通用的术语,用来描述浏览器提供给客户端脚本语言(如JavaScript)的对象集合,这些对象允许开发者与浏览器进行交互。
- 在 BOM 的操作中,最常见的对象是
window
,它代表了浏览器的一个实例,即一个打开的窗口或者一个标签页。通过window
对象,可以访问一系列子对象。 - BOM 还定义了一些控制浏览器行为的方法,比如弹出新窗口的
window.open()
方法,或者是设置定时器的setTimeout()
和setInterval()
方法。 - 开发者可以利用 BOM 来检测浏览器的类型和版本,控制窗口(打开、关闭窗口),甚至是持久化用户信息(通过cookies),但是由于 BOM 并没有一个统一的标准,所以不同的浏览器可能会以不同的方式实现这些对象和方法,这就需要开发者注意兼容性问题。
-
属性
window.location
: 包含有关当前URL的信息,并可以用来重定向浏览器到新的URL。window.history
: 提供对浏览器历史的访问能力。window.screen
: 包含有关用户屏幕的属性,如宽度和高度。window.navigator
: 包含有关用户浏览器的信息,如浏览器名称、版本和操作系统。window.document
: 指向 DOM 文档,与页面内容直接相关。window.innerWidth
和window.innerHeight
: 提供视窗(viewport)的宽度和高度。window.outerWidth
和window.outerHeight
: 提供整个浏览器窗口的宽度和高度,包括窗口的UI部分。
-
方法
window.alert()
: 显示一个带有消息和确认按钮的警告框。window.confirm()
: 显示一个带有消息以及确认和取消按钮的对话框。window.prompt()
: 显示一个用于用户输入的对话框。window.open()
: 打开一个新的浏览器窗口或标签页。window.close()
: 关闭当前窗口。window.moveTo()
和window.resizeTo()
: 用于改变窗口的位置和大小。window.setTimeout()
和window.clearTimeout()
: 设置和清除延时调用函数。window.setInterval()
和window.clearInterval()
: 设置和清除重复调用函数。window.scrollTo()
,window.scrollBy()
和window.scroll()
: 控制窗口滚动。