前端入门学习-JavaScript DOM 全流程操作实战(查找 / 修改 / 事件 / 窗口交互)
前端入门学习笔记(Day09):JavaScript DOM 全流程操作实战(查找 / 修改 / 事件 / 窗口交互)
引入:
在前八天的学习中,我们已掌握 HTML 结构搭建、CSS 样式美化,以及 JavaScript 的变量、函数、流程控制等基础能力(Day01-Day08),但前端开发的核心价值在于 “动态交互”—— 比如用户点击按钮修改内容、提交表单验证数据、缩放窗口实时响应,这些都需要通过操作 DOM(文档对象模型)实现。
DOM 是 HTML 文档的编程接口,将页面元素转化为可被 JavaScript 操作的对象。Day09覆盖 DOM 操作全流程:从 “查找元素”(获取要操作的目标),到 “修改内容与样式”(改变元素呈现),再到 “绑定事件”(响应用户操作),最后到 “窗口与表单交互”(适配页面环境与用户输入)。
一、DOM 元素查找:精准定位页面元素的 4 种核心方法
DOM(文档对象模型)将 HTML 页面解析为树状结构,要操作页面元素,首先需通过 DOM API “找到” 目标元素。Day09 第一个代码文件演示了 4 种常用的元素查找方式,适用于不同场景,是 DOM 操作的基础前提。
1.1 通过 ID 查找(getElementById):唯一元素的快速定位
- 核心特点:id是 HTML 元素的唯一标识(一个页面中不能有重复id),因此getElementById返回单个元素对象,查找效率最高,是开发中定位唯一元素(如页面容器、表单提交按钮)的首选方式。
- 语法:document.getElementById("元素id值")
- 代码解析:
-
// 查找id为"context"的div元素(页面中唯一) var context = document.getElementById("context"); console.log(context); // 输出:<div id="context">...</div>(整个div元素对象) - 使用场景:定位页面中唯一存在的元素,如顶部导航栏、页脚容器、弹窗主体等,结合 Day05 中 “修改元素样式” 的知识点,可快速实现单个元素的动态操作。
1.2 通过类名查找(getElementsByClassName):同类元素的批量获取
- 核心特点:class用于为多个元素定义相同样式或逻辑,因此getElementsByClassName返回HTMLCollection(类数组对象),包含所有指定类名的元素,需通过索引(如[0])或循环遍历单个元素。
- 语法:document.getElementsByClassName("元素class值")
- 代码解析:
// 查找所有class为"text"的p元素(页面中有2个:第一段、第二段文字)
var text = document.getElementsByClassName("text");
console.log(text); // 输出:HTMLCollection(2) [p.text, p.text](类数组对象)
console.log(text[0]); // 输出:<p class="text">第一段文字</p>(第一个class为"text"的元素)
- 注意事项:方法名中 “Elements” 为复数形式(不可省略 “s”),否则会报错;返回的类数组对象不支持 forEach 循环,需用 for 循环遍历(如for(var i=0;i<text.length;i++){...})。
- 使用场景:批量操作同类元素,如商品列表中的所有商品卡片、表单中的所有输入框,结合 Day07 数组遍历的思路,可实现同类元素的统一样式修改或逻辑处理。
1.3 通过标签名查找(getElementsByTagName):同类型元素的全局获取
- 核心特点:根据 HTML 标签名(如p、div、ul)查找元素,返回HTMLCollection(类数组对象),包含页面中所有该类型的元素,适用范围最广,但查找精度较低。
- 语法:document.getElementsByTagName("HTML标签名")
- 代码解析:
// 查找页面中所有p标签元素(共3个:class为text的2个 + class为ptext的1个)
var ptext = document.getElementsByTagName("p");
console.log(ptext); // 输出:HTMLCollection(3) [p.text, p.text, p.ptext]
- 使用场景:获取页面中某一类型的所有元素,如统计页面中图片数量(getElementsByTagName("img"))、清空所有输入框内容(getElementsByTagName("input")),常与 “批量操作” 需求结合。
1.4 通过 CSS 选择器查找(querySelectorAll):灵活精准的多条件匹配
- 核心特点:支持 CSS 选择器语法(如类选择器.、ID 选择器#、后代选择器ul li、伪类选择器:first-child),返回NodeList(类数组对象),可满足复杂的元素查找需求,灵活性最高。
- 语法:document.querySelectorAll("CSS选择器")
- 代码解析:
// 1. 查找ul下的所有li元素(后代选择器)
var allList = document.querySelectorAll("ul li");
console.log(allList); // 输出:NodeList(3) [li, li, li](3个列表项)
// 2. 查找ul下的第一个li元素(伪类选择器:first-child)
var firstList = document.querySelectorAll("ul li:first-child");
console.log(firstList); // 输出:NodeList(1) [li](仅第一个列表项)
// 3. 查找ul下的第二个li元素(伪类选择器:nth-child(1),注意:nth-child从1开始计数)
var secondList = document.querySelectorAll("ul li:nth-child(1)");
console.log(secondList); // 输出:NodeList(1) [li](第二个列表项)
- 优势与注意:
- 相比前三种方法,支持更复杂的选择逻辑(如"div.text > p"选择 class 为 text 的 div 下的直接子 p 元素);
- 返回的 NodeList 对象支持 forEach 循环(如allList.forEach(item => console.log(item))),遍历更便捷;
- 若只需查找单个元素,可使用querySelector(无 “All”),返回匹配的第一个元素(如document.querySelector("ul li:first-child"))。
- 使用场景:复杂条件下的元素查找,如 “查找第三个商品卡片中的加入购物车按钮”“定位表单中带有必填标记的输入框”,是开发中灵活性最高的查找方式。
1.5 四种查找方式的对比与选择建议
|
查找方法 |
返回结果类型 |
查找依据 |
适用场景 |
优势 |
|
getElementById |
单个元素对象 |
元素 id |
定位唯一元素(如容器、按钮) |
效率最高,唯一匹配 |
|
getElementsByClassName |
HTMLCollection |
元素 class |
批量操作同类元素 |
按功能分组查找,灵活 |
|
getElementsByTagName |
HTMLCollection |
HTML 标签名 |
全局获取同类型元素 |
范围广,无需提前定义 class |
|
querySelectorAll |
NodeList |
CSS 选择器 |
复杂条件查找 |
支持多语法,灵活性最高 |
二、DOM 元素内容修改
找到目标元素后,最常见的需求是修改元素内容(如动态更新文本、插入 HTML 结构)。Day09 第二个代码文件对比了textContent与innerHTML两种修改方式,二者核心差异在于是否解析 HTML 标签,需根据场景选择。
2.1 textContent:纯文本内容修改(安全无风险)
- 核心特点:仅修改元素的纯文本内容,不解析 HTML 标签,所有传入的内容都会被当作普通文本显示,避免 XSS(跨站脚本攻击)风险,是纯文本更新的首选方式。
- 语法:元素.textContent = "新的纯文本内容"
- 代码解析:
function changeContext() {
var context = document.getElementById("context");
// 修改为纯文本“这是新的文本信息”,无HTML解析
context.textContent = "这是新的文本信息";
// 页面显示:这是新的文本信息(无格式,纯文字)
}
- 使用场景:动态更新普通文本内容,如商品价格变动、倒计时数字更新、用户昵称显示等,确保内容仅为文字,无 HTML 结构时使用。
2.2 innerHTML:HTML 结构内容修改(支持标签解析)
- 核心特点:可传入包含 HTML 标签的字符串,会解析标签并渲染为 DOM 结构,能实现文本格式美化(如加粗、换行)或插入复杂 HTML 元素,但存在 XSS 风险(若内容来自用户输入,可能注入恶意脚本)。
- 语法:元素.innerHTML = "包含HTML标签的内容"
- 代码解析(结合定时器):
function changeContext() {
var context = document.getElementById("context");
// 2秒后(setTimeout延迟执行),插入带<strong>标签的内容
setTimeout(() => {
context.innerHTML = "<strong>这是你好</strong>";
// 页面显示:这是你好(文字加粗,因<strong>标签被解析)
}, 2000); // 2000ms=2秒,Day07定时器知识点的实际应用
}
- 优势与风险:
- 优势:支持插入复杂 HTML 结构(如<div><p>新内容</p></div>),可快速动态生成页面元素(如商品列表项);
- 风险:若内容包含用户输入(如评论、留言),需先过滤 HTML 标签,否则可能被注入恶意代码(如<script>恶意代码</script>)。
- 使用场景:需要动态插入带格式的文本(如加粗标题、换行说明)或复杂 HTML 结构(如动态生成的表单、弹窗内容)时使用,结合 Day05 “DOM 交互” 知识点,实现页面内容的动态更新。
2.3 textContent 与 innerHTML 的核心差异对比
|
修改方式 |
是否解析 HTML 标签 |
安全性 |
适用场景 |
示例结果 |
|
textContent |
否 |
高(无 XSS) |
纯文本更新(价格、数字) |
输入<strong>文本</strong>,显示<strong>文本</strong> |
|
innerHTML |
是 |
低(需过滤) |
带格式文本或 HTML 结构插入 |
输入<strong>文本</strong>,显示文本(加粗) |
2.4 用 JavaScript 动态修改 DOM 元素样式:操作 style 属性
在前端开发中,通过 JS 动态修改元素样式是实现 “交互反馈” 的核心手段(如按钮点击后变色、表单验证失败时标红输入框)。Day09 第三个代码文件聚焦style属性的使用,直接操作 DOM 元素的内联样式,弥补了 CSS 静态样式无法响应交互的不足。
2.4.1 核心原理:style 属性与 CSS 样式的映射关系
DOM 元素的style属性是一个对象,其属性名对应 CSS 样式名,但需将 CSS 的 “短横线命名” 转为 JS 的 “驼峰命名”(如 CSS 中的font-size对应 JS 中的fontSize、background-color对应backgroundColor)。通过给style属性赋值,可直接修改元素的内联样式,且优先级高于外部 CSS(Day05 曾提及内联样式优先级特性)。
2.4.2 代码实战:点击按钮修改 div 样式
第三个文件中,通过按钮点击触发changeContext()函数,获取 div 元素后修改其文本颜色和字体大小,完整逻辑解析如下:
<!DOCTYPE html>
<html>
<head>
<title>js学习</title>
<style>
.box{ /* 初始CSS样式:内边距和外边距 */
padding:20px;
margin:20px;
}
</style>
</head>
<body>
<!-- 目标div:初始文本为Hello World,拥有box类 -->
<div id="context" class="box">Hello World</div>
<!-- 点击按钮触发修改样式的函数 -->
<button onclick="changeContext()">修改css样式</button>
<script>
function changeContext(){
// 1. 通过id获取目标div元素(Day09第一部分学习的元素查找方法)
var divDemo = document.getElementById("context");
// 2. 修改style属性:动态设置内联样式
divDemo.style.color = "red"; // 文本颜色改为红色(对应CSS的color)
divDemo.style.fontSize = "20px"; // 字体大小改为20px(对应CSS的font-size)
// 拓展:可添加更多样式修改
divDemo.style.backgroundColor = "#f5f5f5"; // 背景色改为浅灰色
divDemo.style.border = "1px solid #ddd"; // 添加灰色边框
}
</script>
</body>
</html>
执行效果:点击按钮后,div 文本从默认样式变为 “红色、20px 字体、浅灰色背景 + 灰色边框”,直观体现了 JS 动态修改样式的作用。
2.4.3 注意事项与拓展场景
- 样式单位不可省略:设置fontSize、width等需要单位的样式时,必须添加单位(如20px而非20),否则样式不生效;
- 优先级问题:style属性设置的内联样式会覆盖外部 CSS(如.box类的样式),若需恢复默认样式,可将style属性设为空字符串(如divDemo.style.color = "");
- 常见应用场景:表单验证(输入错误时标红输入框)、导航栏 hover 效果(JS 实现更复杂的过渡)、主题切换(点击按钮切换整体页面颜色)。
2.5 JavaScript DOM 事件:绑定与触发交互逻辑
DOM 事件是 “用户操作” 与 “JS 逻辑” 的桥梁(如点击、双击、鼠标移入等操作触发对应函数)。Day09 第四个代码文件对比了 “HTML 属性绑定事件” 和 “addEventListener 绑定事件” 两种方式,重点演示了更灵活的addEventListener方法,是实现复杂交互的基础。
2.5.1 常见 DOM 事件类型:覆盖主流用户操作
代码文件中列出了前端开发常用的鼠标事件,补充完整分类及说明如下:
|
事件类型 |
触发条件 |
应用场景 |
|
onclick |
鼠标左键单击元素 |
按钮点击提交表单、跳转页面 |
|
ondblclick |
鼠标左键双击元素 |
双击打开文件、放大图片 |
|
onmousedown |
鼠标按下(未松开)时 |
拖拽功能的开始(如拖拽元素) |
|
onmouseup |
鼠标按下后松开时 |
拖拽功能的结束、确认操作 |
|
onmouseover |
鼠标移入元素范围时 |
显示下拉菜单、图片预览 |
|
onmouseout |
鼠标移出元素范围时 |
隐藏下拉菜单、关闭预览 |
|
oninput |
输入框内容变化时(拓展) |
实时搜索提示、输入字数统计 |
2.5.2 两种事件绑定方式:HTML 属性绑定 vs addEventListener
第四个代码文件隐性对比了两种绑定方式,二者在灵活性、可维护性上差异显著,具体分析如下:
(1)HTML 属性绑定事件(简单但不推荐)
通过在 HTML 标签中添加onclick、ondblclick等属性,直接指定触发的函数,如代码中注释的写法:
<!-- HTML标签中绑定事件:直接调用changeContext函数 -->
<button onclick="changeContext()">修改css样式</button>
<div id="context" class="box" ondblclick="alert('我被双击了')">Hello World</div>
<script>
function changeContext(){
alert("我被点中了");
}
</script>
优缺点:
- 优点:语法简单,适合快速实现简单交互;
- 缺点:HTML 与 JS 耦合(修改函数名需同时改 HTML 和 JS)、无法给同一个事件绑定多个函数(如一个按钮点击同时触发 “提交表单” 和 “显示提示”)、动态生成的元素无法绑定(如 JS 新增的按钮无法通过此方式绑定事件)。
(2)addEventListener 绑定事件(推荐,代码文件重点演示)
通过 JS 的addEventListener方法给 DOM 元素绑定事件,将 HTML 与 JS 完全分离,支持绑定多个函数、动态元素绑定等,是开发中的主流方式。第四个文件的核心代码如下:
<div id="context" class="box">Hello World</div>
<script>
// 1. 获取目标div元素
var divContent = document.getElementById("context");
// 2. 用addEventListener绑定双击事件(ondblclick对应事件类型为'dblclick')
divContent.addEventListener('dblclick', () => {
alert("我被选中了"); // 事件触发时执行的逻辑
});
// 拓展:给同一个元素的同一个事件绑定多个函数
divContent.addEventListener('dblclick', () => {
console.log("双击事件被触发,同时打印日志"); // 第二个函数也会执行
});
</script>
语法解析:
element.addEventListener(事件类型, 事件处理函数, [捕获/冒泡阶段])
- 事件类型:需去掉on前缀(如ondblclick改为dblclick、onclick改为click);
- 事件处理函数:可写匿名函数(如代码中的箭头函数),也可写命名函数;
- 第三个参数(可选):布尔值,true表示捕获阶段触发,false(默认)表示冒泡阶段触发(后续事件流会深入)。
优缺点:
- 优点:HTML 与 JS 解耦(便于维护)、支持给同一个事件绑定多个函数、可通过removeEventListener移除事件(避免内存泄漏)、支持动态生成的元素绑定(后续事件委托会学习);
- 缺点:语法稍复杂,需先获取元素再绑定。
2.5.3 实战拓展:给按钮绑定多个点击事件
以 “点击按钮同时提交表单和显示成功提示” 为例,演示addEventListener绑定多个函数的优势:
<form id="myForm">
<input type="text" name="username" placeholder="请输入用户名">
<button type="button" id="submitBtn">提交</button>
</form>
<script>
var submitBtn = document.getElementById("submitBtn");
var myForm = document.getElementById("myForm");
// 第一个点击事件处理函数:提交表单
function submitForm() {
myForm.submit(); // 提交表单
}
// 第二个点击事件处理函数:显示成功提示
function showTip() {
alert("提交成功,正在跳转...");
}
// 给按钮绑定两个点击事件:点击时同时执行两个函数
submitBtn.addEventListener('click', submitForm);
submitBtn.addEventListener('click', showTip);
</script>
执行效果:点击 “提交” 按钮,会同时触发 “表单提交” 和 “显示成功提示”,这是 HTML 属性绑定方式无法实现的。
三、表单事件
3.1 表单事件:submit 提交与默认行为阻止
表单是前端与用户交互的核心组件(如登录、注册、信息提交),Day09 第五个文件聚焦表单的submit事件,重点演示了 “表单提交验证” 与 “默认行为阻止”,这是避免页面刷新、实现异步提交的关键。
3.1.1 表单事件的核心逻辑
表单默认提交行为会触发页面刷新(传统方式将数据发送给服务器后跳转页面),但实际开发中(如 AJAX 异步提交)需先验证数据有效性,再决定是否提交。第五个文件通过addEventListener绑定submit事件,配合e.preventDefault()实现 “先验证、后提交” 的逻辑:
- submit事件:当用户点击表单的 “提交按钮”(type="submit")或按回车键时触发;
- e.preventDefault():阻止事件的默认行为(即阻止表单刷新提交),为自定义验证逻辑留出空间。
3.1.2 代码解析与拓展
<form id="myForm">
<input type="text" name="username" required placeholder="输入用户名" >
<button type="submit">提交</button>
<button type="reset">重置</button>
</form>
<script>
const form = document.getElementById("myForm");
// 绑定submit事件,e为事件对象
form.addEventListener("submit", (e) => {
// 1. 阻止表单默认提交行为(关键步骤,避免页面刷新)
e.preventDefault();
// 2. 自定义验证逻辑(拓展:在原代码基础上补充用户名合法性校验)
const username = form.querySelector('input[name="username"]').value;
// 验证用户名长度(如至少3个字符)
if (username.length < 3) {
alert("用户名长度不能少于3个字符,请重新输入!");
return; // 验证失败,终止后续操作
}
// 3. 验证通过,执行提交逻辑(如发送AJAX请求,后续会学习)
alert("表单验证通过,准备提交");
// 实际开发中此处会写:axios.post("/submit", { username })...
});
</script>
补充说明:
- 表单中的required属性是 HTML5 自带的基础验证(为空时阻止提交),但仅靠前端验证不安全,需配合后端二次验证;
- reset按钮(type="reset")无需额外 JS 逻辑,点击后会自动清空表单内所有输入框的值,适合 “重新填写” 场景。
3.2 文档 / 窗口事件:load 事件与页面资源加载监听
第六个文件演示了window对象的load事件,用于监听 “页面所有资源加载完成” 的时机,这在需要操作图片、脚本等外部资源的场景中至关重要(如图片加载完成后获取尺寸、初始化依赖外部资源的插件)。
3.2.1 load 事件的触发时机
load事件是window对象的核心事件之一,其触发时机是 “页面中所有资源(HTML 结构、CSS 样式、图片、脚本文件、字体等)完全加载完成后”,区别于DOMContentLoaded事件(仅 HTML 结构加载完成即触发,不等待图片等资源)。
第六个文件的代码逻辑:当页面中模拟的 “大图片” 及其他资源加载完成后,弹出提示框,确保后续操作不会因资源未加载而报错:
<script>
// 给window绑定load事件
window.addEventListener("load", () => {
alert("页面图片、脚本等所有资源都加载完成了");
// 拓展:此时可安全操作图片资源(如获取图片尺寸)
const img = document.querySelector("img");
console.log("图片宽度:", img.offsetWidth);
console.log("图片高度:", img.offsetHeight);
});
</script>
<!-- 模拟需要加载的外部图片(实际开发中src为真实图片地址) -->
<img src="https://example.com/large-image.jpg" alt="大图片">
3.2.2 应用场景与注意事项
- 适用场景:
- 图片加载完成后裁剪、压缩或获取尺寸;
- 初始化依赖外部脚本的插件(如地图插件、图表插件);
- 确保页面所有样式加载完成后再执行 DOM 样式修改,避免样式闪烁。
- 注意事项:
- load事件触发时机较晚,若仅需操作 HTML 结构(如给 DOM 元素绑定事件),推荐使用DOMContentLoaded事件,提升页面响应速度;
- 若页面中存在加载失败的资源(如图片 404),load事件仍会正常触发,不会因个别资源加载失败而阻塞。
3.2.3 拓展:DOMContentLoaded 事件对比
为了更清晰区分load与DOMContentLoaded,补充代码示例,帮助理解两者的差异:
<script>
// 1. DOMContentLoaded:HTML结构加载完成即触发(不等待图片)
document.addEventListener("DOMContentLoaded", () => {
console.log("HTML结构加载完成,可操作DOM元素");
});
// 2. load:所有资源加载完成后触发(包括图片)
window.addEventListener("load", () => {
console.log("所有资源加载完成,可操作图片等外部资源");
});
</script>
<img src="https://example.com/large-image.jpg" alt="大图片">
执行结果:先打印 “HTML 结构加载完成...”,后打印 “所有资源加载完成...”,体现了两者的触发时机差异。
四、窗口缩放和页面滚动
4.1 窗口缩放事件(resize):响应式交互的核心触发
窗口缩放事件(resize)是前端实现 “响应式交互” 的关键事件之一,当浏览器窗口的宽度或高度发生变化时会自动触发。第七个文件通过 “窗口缩放时更新尺寸显示” 的案例,演示了resize事件的基础应用,其核心价值在于适配不同设备屏幕尺寸(如 PC 端窗口缩小、移动端横屏 / 竖屏切换)时的界面调整。
4.1.1 基础语法与事件绑定
resize事件需绑定到window对象(代表浏览器窗口),通过addEventListener实现事件监听,语法结构如下:
// 绑定窗口缩放事件
window.addEventListener("resize", () => {
// 窗口缩放时执行的逻辑(如更新尺寸显示、调整DOM布局)
});
4.1.2 实战解析:窗口缩放时更新尺寸文本
第七个文件的核心逻辑是 “当窗口缩放时,修改p标签的文本内容”,但代码中固定将文本设为"200px",实际开发中更常用 “动态获取窗口实时尺寸” 的方式优化,完整优化代码如下:
// 1. 获取显示尺寸的DOM元素
const sizeText = document.getElementById("windowSize");
// 2. 定义更新尺寸的函数(复用逻辑,避免重复代码)
function updateWindowSize() {
// 获取窗口实时宽度(window.innerWidth)和高度(window.innerHeight)
const windowWidth = window.innerWidth;
const windowHeight = window.innerHeight;
// 动态更新文本内容,显示当前窗口尺寸
sizeText.textContent = `窗口宽度:${windowWidth}px,窗口高度:${windowHeight}px`;
}
// 3. 绑定窗口缩放事件:缩放时触发更新
window.addEventListener("resize", updateWindowSize);
// 4. 初始加载时执行一次:确保页面打开就显示正确尺寸
updateWindowSize();
4.1.3 关键 API:获取窗口尺寸的核心属性
- window.innerWidth:获取浏览器窗口的 “可视区域宽度”(包含滚动条宽度,不包含浏览器边框);
- window.innerHeight:获取浏览器窗口的 “可视区域高度”(包含滚动条高度,不包含浏览器顶部导航栏);
- 若需排除滚动条宽度,可使用document.documentElement.clientWidth(仅可视区域,不含滚动条),需根据实际需求选择。
4.1.4 实际应用场景
- 响应式布局调整:如窗口宽度小于 768px 时,隐藏 PC 端导航栏、显示移动端菜单;
- 图表适配:如 ECharts 图表在窗口缩放时,调用resize()方法重新渲染图表尺寸;
- 元素定位修正:如固定在窗口右侧的 “返回顶部” 按钮,在窗口缩小时调整右侧距离。
4.2 页面滚动事件(scroll):滚动交互的基础触发
页面滚动事件(scroll)在用户滚动页面(垂直滚动或水平滚动)时触发,第八个文件通过 “滚动页面时显示滚动距离” 的案例,演示了scroll事件的应用,其核心价值在于实现 “滚动到指定位置显示元素”“滚动进度条”“导航栏吸顶” 等常见交互效果。
4.2.1 基础语法与事件绑定
与resize事件类似,scroll事件也需绑定到window对象(或可滚动的 DOM 元素,如带overflow: auto的容器),基础语法如下:
// 绑定页面滚动事件(全局滚动)
window.addEventListener("scroll", () => {
// 页面滚动时执行的逻辑(如获取滚动距离、控制元素显示/隐藏)
});
// 绑定局部元素滚动事件(如带滚动条的div)
const scrollContainer = document.getElementById("scrollContainer");
scrollContainer.addEventListener("scroll", () => {
// 局部元素滚动时执行的逻辑
});
4.2.2 实战解析:滚动时显示垂直滚动距离
第八个文件的核心逻辑是 “滚动页面时,更新固定定位的p标签文本”,但代码中固定设为"ssss",实际开发中需 “动态获取垂直滚动距离” 并显示,完整优化代码如下:
// 1. 获取显示滚动距离的DOM元素(固定在页面右上角)
const posText = document.getElementById('scrollPos');
// 2. 定义更新滚动距离的函数
function updateScrollPosition() {
// 获取页面垂直滚动距离:window.scrollY(等价于document.documentElement.scrollTop)
const scrollDistance = window.scrollY;
// 动态更新文本内容,显示当前滚动距离
posText.textContent = `滚动距离:${scrollDistance}px`;
}
// 3. 绑定页面滚动事件:滚动时触发更新
window.addEventListener('scroll', updateScrollPosition);
// 4. 初始加载时执行一次:确保页面打开时显示初始滚动距离(0px)
updateScrollPosition();
4.2.3 关键 API:获取滚动距离的核心属性
- 垂直滚动距离:
- window.scrollY:返回页面从顶部开始的垂直滚动距离(单位:px),兼容性较好;
- document.documentElement.scrollTop:与scrollY功能一致,部分旧浏览器需用此属性兼容;
- 水平滚动距离:
- window.scrollX(或document.documentElement.scrollLeft):返回页面从左侧开始的水平滚动距离,适用于横向滚动的页面。
4.2.4 实际应用场景
- 滚动进度条:根据scrollY与 “页面总高度” 的比例,动态设置进度条的宽度;
- 元素懒加载:滚动到指定位置时,才加载图片或请求数据(减少初始加载压力);
- 导航栏吸顶:当滚动距离超过导航栏顶部时,给导航栏添加position: fixed样式,固定在页面顶部;
- 回到顶部按钮:当滚动距离大于 500px 时显示 “回到顶部” 按钮,点击后通过window.scrollTo(0, 0)回到页面顶部。
4.2.5 性能优化:避免滚动事件高频触发
scroll事件的特点是 “高频触发”(滚动过程中每秒触发数十次),直接在事件回调中执行复杂逻辑(如 DOM 操作、数据计算)会导致页面卡顿。实际开发中可通过 “防抖(debounce)” 优化,减少事件触发次数,示例代码如下:
// 防抖函数:延迟执行回调,避免高频触发
function debounce(func, delay = 100) {
let timer = null; // 定时器标识
return function() {
clearTimeout(timer); // 每次触发时清除之前的定时器
// 延迟delay毫秒后执行函数
timer = setTimeout(() => {
func.apply(this, arguments);
}, delay);
};
}
// 用防抖函数包装更新滚动距离的逻辑,延迟100ms执行
const debouncedUpdate = debounce(updateScrollPosition);
// 绑定优化后的滚动事件
window.addEventListener('scroll', debouncedUpdate);
通过防抖优化,滚动过程中仅在 “停止滚动 100ms 后” 执行一次逻辑,大幅降低性能消耗。
五、总结
Day09 围绕 JavaScript DOM 操作展开,核心是掌握 “找到元素→修改元素→响应交互” 的完整逻辑:通过 ID、类名、标签、CSS 选择器等方式精准查找 DOM 元素,利用textContent/innerHTML和style属性分别修改元素内容与样式,再通过addEventListener绑定鼠标、表单、文档、窗口等多类事件,实现用户操作与页面反馈的联动。整套知识点串联起前端动态交互的核心流程,解决了 “如何让静态页面动起来” 的核心问题,为后续开发复杂交互功能打下坚实基础。
更多推荐
所有评论(0)