从零吃透 JavaScript WebAPI:DOM+BOM 实战指南
文章目录
在前端开发的世界里,JavaScript 就像一门武功——ECMAScript 是扎马步的基础内功,而 WebAPI 则是闯荡江湖的招式套路。想要写出能响应用户操作、动态交互的网页,WebAPI 是绕不开的核心技能。本文将以更通俗的视角、更细致的拆解,带大家全面掌握 WebAPI 的核心用法,从概念到实战一步到位。
一、WebAPI 基础认知:先搞懂「是什么」和「为什么」
1.1 WebAPI 到底是什么?
很多新手会混淆 JavaScript 和 WebAPI 的关系,其实答案很简单:
- JavaScript 由三部分组成:ECMAScript(基础语法)、DOM API(操作页面结构)、BOM API(操作浏览器)
- WebAPI 就是 DOM + BOM 的集合,是 W3C 组织制定的标准(和制定 ECMAScript 的 ECMA 国际不是同一波人)
打个比方:ECMAScript 教会你「如何发力」,而 WebAPI 告诉你「怎么出招」——没有基础语法,你连函数、变量都不会写;但没有 WebAPI,你写的代码只能在控制台跑,没法和网页互动。
1.2 什么是 API?
API 是「应用程序编程接口」的缩写,本质上就是别人写好的现成函数或对象,供我们直接调用。就像你用手机拍照,不用自己造摄像头、写成像算法,只需要点击「拍照按钮」这个接口就行。
WebAPI 就是浏览器提供的「网页操作接口」,比如让你获取页面上的按钮、修改文字、监听用户点击等,不用关心浏览器底层是怎么实现的,直接调用接口即可。
1.3 去哪里查 API 文档?
学习 WebAPI 离不开权威文档,最推荐的是 MDN(Mozilla 开发者网络):
- 官方地址:https://developer.mozilla.org/zh-CN/docs/Web/API
- 搜索技巧:直接在搜索引擎输入「MDN + API 名称」,比如「MDN querySelector」,能快速找到对应用法
二、DOM 核心:网页的「结构骨架」操作指南
2.1 什么是 DOM?
DOM 全称「Document Object Model」(文档对象模型),W3C 标准给我们提供了一系列函数,让我们能操作网页的三大核心:
- 内容:比如修改文章文字、替换图片
- 结构:比如添加一个新按钮、删除一个列表项
- 样式:比如改变字体颜色、调整元素大小
2.2 理解 DOM 树:网页结构的「家谱图」
一个网页的结构本质上是一棵「树形结构」,我们称之为 DOM 树。可以把它想象成一个家谱:
- 根节点:整个文档(document),相当于「家族祖先」
- 根元素:
<html>标签,是所有网页元素的「父节点」 - 子节点:
<head>和<body>,是<html>的直接后代 - 孙节点:
<title>、<a>、<h1>等,是<head>或<body>的后代 - 叶子节点:文本内容、属性等,比如
<h1>里的「我的标题」
举个简单的 HTML 结构对应的 DOM 树:
<html><head><title>文档标题</title></head><body><ahref="https://xxx.com">我的链接</a><h1>我的标题</h1></body></html>对应的 DOM 树结构:
文档(document) └── <html> ├── <head> │ └── <title> │ └── 文本:"文档标题" └── <body> ├── <a>(属性:href="https://xxx.com") │ └── 文本:"我的链接" └── <h1> └── 文本:"我的标题" 理解 DOM 树是操作网页的关键——所有操作都要先找到对应的「节点」(元素、文本、属性),再进行修改。
2.3 核心操作 1:获取元素(找到 DOM 树中的「目标节点」)
想要操作元素,第一步必须是「找到它」。WebAPI 提供了多种获取元素的方法,其中最常用、最灵活的是 querySelector 和 querySelectorAll(HTML5 新增,IE9+ 支持)。
2.3.1 querySelector:获取「第一个匹配」的元素
语法:var 元素对象 = 父元素.querySelector('CSS选择器');
- 参数:有效的 CSS 选择器(比如
.class、#id、标签名、后代选择器等) - 返回值:匹配到的第一个元素对象;如果没找到,返回
null - 特点:可以在任意元素上调用,不止
document(调用的元素会作为查找的根节点)
实战示例:
<divclass="box">abc</div><divid="user-id">def</div><h3><span><inputtype="text"></span></h3><script>// 1. 类选择器:获取 .box 元素var elem1 = document.querySelector('.box'); console.log(elem1);// 输出 <div>abc</div>// 2. ID 选择器:获取 #user-id 元素var elem2 = document.querySelector('#user-id'); console.log(elem2);// 输出 <div>def</div>// 3. 后代选择器:获取 h3 > span > input 元素var elem3 = document.querySelector('h3 span input'); console.log(elem3);// 输出 <input type="text">// 4. 限定根节点查找:只在 elem1 内部找 span(这里没有,返回 null)var elem4 = elem1.querySelector('span'); console.log(elem4);// null</script>2.3.2 querySelectorAll:获取「所有匹配」的元素
语法:var 元素集合 = 父元素.querySelectorAll('CSS选择器');
- 参数:和
querySelector一样,是 CSS 选择器 - 返回值:一个「类数组对象」(NodeList),包含所有匹配的元素;如果没找到,返回空的类数组
- 特点:返回的集合不是数组,但可以用
for循环遍历;集合是「动态的」,如果页面元素变化,集合会自动更新
实战示例:
<divclass="box">abc</div><divclass="box">def</div><divid="user-id">ghi</div><script>// 获取所有 div 元素var allDivs = document.querySelectorAll('div'); console.log(allDivs);// 输出 NodeList(3) [div.box, div.box, div#user-id]// 遍历所有 .box 元素var boxList = document.querySelectorAll('.box');for(var i =0; i < boxList.length; i++){ console.log(boxList[i].innerText);// 依次输出 "abc"、"def"}</script>注意事项:
- 选择器必须是有效的 CSS 选择器,否则会报错(比如
querySelector('#user id')会因为空格报错) - ID 选择器虽然可以用,但建议页面中 ID 唯一,避免匹配错误
- 如果需要兼容 IE8 及以下,可能需要用
getElementById、getElementsByClassName等旧方法,但现在大部分项目已不再兼容旧浏览器
2.4 核心操作 2:操作元素内容(修改 DOM 树的「文本节点」)
获取到元素后,最常用的操作就是修改它的内容。主要有两个属性:innerText 和 innerHTML,用法类似但适用场景不同。
2.4.1 innerText:纯文本操作(不识别 HTML 标签)
- 作用:获取或设置元素的「渲染后文本内容」
- 特点:
- 不识别 HTML 标签,会把标签当成普通文本
- 不保留 HTML 源码中的换行和空格(会按照页面渲染的样子显示)
- 非标准属性(由 IE 发起,现在大部分浏览器支持)
语法:
// 读操作:获取元素文本var 文本内容 = 元素.innerText;// 写操作:设置元素文本 元素.innerText ='新的文本内容';实战示例:
<divclass="content"><span>hello world</span><span>hello world</span></div><script>var contentDiv = document.querySelector('.content');// 读操作:获取文本 console.log(contentDiv.innerText);// 输出:"hello world hello world"(没有标签,换行被合并)// 写操作:设置文本(span 标签会被当成普通文本) contentDiv.innerText ='hello js <span>这是标签</span>';// 页面显示:hello js <span>这是标签</span>(标签没有生效)</script>2.4.2 innerHTML:HTML 结构操作(识别 HTML 标签)
- 作用:获取或设置元素的「HTML 结构内容」
- 特点:
- 识别 HTML 标签,设置时会解析标签并渲染
- 保留 HTML 源码中的换行和空格
- W3C 标准属性,兼容性更好,使用场景更广
语法:
// 读操作:获取 HTML 结构varHTML内容 = 元素.innerHTML;// 写操作:设置 HTML 结构 元素.innerHTML ='<标签>新的内容</标签>';实战示例:
<divclass="content"><span>hello world</span><span>hello world</span></div><script>var contentDiv = document.querySelector('.content');// 读操作:获取 HTML 结构 console.log(contentDiv.innerHTML);// 输出:"\n <span>hello world</span>\n <span>hello world</span>\n"(保留换行和标签)// 写操作:设置 HTML 结构(span 标签会被解析) contentDiv.innerHTML ='<span>hello js</span>';// 页面显示:红色的 "hello js"(标签生效)</script>两者对比与选择:
| 特性 | innerText | innerHTML |
|---|---|---|
| 识别 HTML 标签 | 否 | 是 |
| 保留换行/空格 | 否(按渲染结果) | 是(按源码) |
| 兼容性 | IE 发起,大部分浏览器支持 | W3C 标准,全浏览器支持 |
| 适用场景 | 纯文本展示/修改 | 需修改 HTML 结构时 |
推荐用法:大部分场景下优先用 innerHTML,因为它更灵活,能直接操作结构;如果只是简单的文本修改,用 innerText 也可以(避免解析 HTML 带来的性能损耗)。
2.5 核心操作 3:操作元素属性(修改 DOM 树的「属性节点」)
元素的属性(比如 <img> 的 src、alt,<a> 的 href 等)也可以通过 DOM 操作来获取和修改。直接通过「元素对象.属性名」即可操作。
2.5.1 常见属性操作示例(普通元素)
以 <img> 标签为例:
<imgsrc="rose.jpg"alt="这是一朵花"title="玫瑰花"width="200"><script>var img = document.querySelector('img');// 1. 读操作:获取属性值 console.log(img.src);// 输出图片完整路径(比如 "file:///xxx/rose.jpg") console.log(img.alt);// 输出 "这是一朵花" console.log(img.title);// 输出 "玫瑰花" console.log(img.width);// 输出 200// 2. 写操作:修改属性值(页面会实时更新) img.onclick=function(){// 点击图片切换 src 属性,实现图片切换if(img.src.includes('rose.jpg')){ img.src ='rose2.jpg'; img.alt ='这是另一朵花'; img.title ='红玫瑰';}else{ img.src ='rose.jpg'; img.alt ='这是一朵花'; img.title ='玫瑰花';}}</script>2.5.2 表单元素属性操作(重点!)
表单元素(比如 <input>、<select>、<textarea>)的属性操作有特殊性,核心关注以下几个属性:
value:输入框/按钮的内容disabled:是否禁用(true禁用,false启用)checked:复选框/单选框是否选中selected:下拉框选项是否选中type:输入框类型(文本、密码、按钮等)
示例 1:按钮文本切换(播放/暂停)
<inputtype="button"value="播放"><script>var btn = document.querySelector('input'); btn.onclick=function(){if(btn.value ==='播放'){ btn.value ='暂停';// 切换按钮文本}else{ btn.value ='播放';}}</script>示例 2:点击计数(输入框数值递增)
<inputtype="text"id="count"value="0"><inputtype="button"id="addBtn"value="点我+1"><script>var countInput = document.querySelector('#count');var addBtn = document.querySelector('#addBtn'); addBtn.onclick=function(){// 注意:input.value 是字符串,需要转成数字var currentNum =Number(countInput.value); currentNum++;// 数值递增 countInput.value = currentNum;// 回显到输入框}</script>示例 3:复选框全选/取消全选
<inputtype="checkbox"id="allSelect"> 全选<br><inputtype="checkbox"class="item"> 选项1<br><inputtype="checkbox"class="item"> 选项2<br><inputtype="checkbox"class="item"> 选项3<br><inputtype="checkbox"class="item"> 选项4<br><script>var allSelect = document.querySelector('#allSelect');var itemList = document.querySelectorAll('.item');// 1. 点击全选框:选中/取消所有选项 allSelect.onclick=function(){// 遍历所有选项,把它们的 checked 设为和全选框一致for(var i =0; i < itemList.length; i++){ itemList[i].checked = allSelect.checked;}}// 2. 点击单个选项:判断是否需要取消全选for(var i =0; i < itemList.length; i++){ itemList[i].onclick=function(){// 检查所有选项是否都被选中var isAllChecked =true;for(var j =0; j < itemList.length; j++){if(!itemList[j].checked){ isAllChecked =false;break;// 只要有一个没选中,就不用继续检查了}}// 把全选框的 checked 设为检查结果 allSelect.checked = isAllChecked;}}</script>三、事件基础:让网页「感知」用户操作
3.1 什么是事件?
用户在网页上的每一个操作(点击、输入、移动鼠标等),都会在浏览器中触发一个「事件」。JavaScript 可以监听这些事件,然后执行对应的代码——这就是网页交互的核心。
可以用一个生动的比喻理解:
- 浏览器 = 哨兵
- 用户操作 = 敌情
- 事件 = 烽火台的狼烟
- 事件处理程序 = 后方的应对策略
3.2 事件三要素(缺一不可)
想要实现事件交互,必须满足三个条件:
- 事件源:哪个元素触发的事件(比如按钮、输入框)
- 事件类型:用户做了什么操作(比如点击
click、输入input、鼠标移动mousemove) - 事件处理程序:触发事件后要执行的代码(通常是一个函数)
3.3 事件注册(绑定):告诉浏览器「要监听什么」
事件注册就是把「事件源、事件类型、事件处理程序」关联起来。最常用的方式是「属性绑定」(直接在元素上或通过 JS 绑定)。
基础示例:点击按钮弹出提示
<buttonid="btn">点我一下</button><script>// 1. 获取事件源(按钮)var btn = document.getElementById('btn');// 2. 注册事件(绑定 click 事件) btn.onclick=function(){// 3. 事件处理程序(触发点击后执行)alert('hello world!你点击了按钮');}</script>关键说明:
- 事件处理程序是一个「回调函数」:不需要我们主动调用,浏览器会在事件触发时自动执行
- 事件类型有很多:除了
click,还有input(输入框输入)、blur(输入框失去焦点)、load(页面加载完成)等 - 可以给同一个元素绑定多个不同类型的事件,但同一类型的事件只能绑定一个处理程序(后面的会覆盖前面的)
3.4 常见事件类型(入门必学)
| 事件类型 | 触发场景 | 常用元素 |
|---|---|---|
| click | 鼠标左键点击元素 | 按钮、链接、复选框等 |
| dblclick | 鼠标左键双击元素 | 任意元素 |
| input | 输入框内容变化(实时) | input、textarea |
| change | 输入框内容变化(失去焦点后) | input、select、textarea |
| blur | 元素失去焦点 | input、textarea |
| focus | 元素获得焦点 | input、textarea |
| mousemove | 鼠标在元素上移动 | 任意元素 |
| mouseenter | 鼠标进入元素 | 任意元素 |
| mouseleave | 鼠标离开元素 | 任意元素 |
| load | 页面或资源(图片)加载完成 | window、img |
四、实战综合案例:把知识串起来
下面通过一个综合案例,把「获取元素、操作内容、操作属性、事件绑定」全部用起来,实现一个简单的「待办事项列表」。
需求:
- 输入框输入待办内容,点击「添加」按钮,把内容添加到列表中
- 点击列表项前的复选框,标记为已完成(文字变灰色、加删除线)
- 点击「删除」按钮,删除对应的待办项
- 点击「清空全部」按钮,删除所有待办项
代码实现:
<divclass="todo-container"><h2>待办事项列表</h2><divclass="todo-input"><inputtype="text"id="todoInput"placeholder="请输入待办事项..."><buttonid="addBtn">添加</button><buttonid="clearBtn">清空全部</button></div><ulid="todoList"></ul></div><style>.completed{color: #999;text-decoration: line-through;}</style><script>// 1. 获取所有需要操作的元素var todoInput = document.querySelector('#todoInput');var addBtn = document.querySelector('#addBtn');var clearBtn = document.querySelector('#clearBtn');var todoList = document.querySelector('#todoList');// 2. 添加待办事项 addBtn.onclick=function(){// 获取输入框内容(去除前后空格)var todoText = todoInput.value.trim();if(todoText ===''){alert('请输入待办事项!');return;}// 创建新的列表项(li)var li = document.createElement('li');// 设置 li 的 HTML 结构 li.innerHTML =` <input type="checkbox"> <span>${todoText}</span> <button>删除</button> `;// 把 li 添加到列表中 todoList.appendChild(li);// 清空输入框 todoInput.value ='';// 3. 给新添加的复选框和删除按钮绑定事件bindTodoEvents(li);};// 4. 绑定待办项的事件(复选框+删除按钮)functionbindTodoEvents(li){var checkBox = li.querySelector('.todo-check');var todoText = li.querySelector('.todo-text');var deleteBtn = li.querySelector('.delete-btn');// 复选框事件:标记已完成/未完成 checkBox.onclick=function(){if(checkBox.checked){ todoText.classList.add('completed');// 添加样式类}else{ todoText.classList.remove('completed');// 移除样式类}};// 删除按钮事件:删除当前列表项 deleteBtn.onclick=function(){if(confirm('确定要删除这个待办项吗?')){ todoList.removeChild(li);}};}// 5. 清空全部待办项 clearBtn.onclick=function(){if(todoList.children.length ===0){alert('没有待办事项可以清空!');return;}if(confirm('确定要清空所有待办项吗?')){ todoList.innerHTML ='';// 清空列表}};// 6. 支持按回车键添加待办项 todoInput.onkeydown=function(event){if(event.key ==='Enter'){ addBtn.onclick();// 触发添加按钮的点击事件}};</script>案例说明:
- 用到了
querySelector获取元素、innerHTML操作结构、classList操作样式类 - 事件绑定包括
click(按钮、复选框)、keydown(回车键) - 通过
createElement创建新元素、appendChild添加元素、removeChild删除元素 - 实现了用户交互的核心逻辑:输入、添加、标记完成、删除、清空
五、总结与学习建议
WebAPI 的核心就是「操作 DOM + 监听事件」,掌握了这两点,就能实现绝大多数网页交互效果。想要熟练运用,建议按以下步骤学习:
- 先记牢核心 API:
querySelector/querySelectorAll、innerText/innerHTML、常见事件类型 - 多做小练习:比如图片切换、选项卡、计数器等,把每个知识点单独练熟
- 尝试综合案例:比如待办列表、购物车、表单验证等,把知识点串联起来
- 多看别人的代码:遇到不懂的交互效果,打开浏览器控制台(F12),查看元素和 JS 代码
- 善用 MDN 文档:遇到不会的 API,第一时间查 MDN,看示例代码和参数说明
记住:前端开发是「实践型」技能,光看理论没用,一定要多写代码、多调试。刚开始可能会遇到「找不到元素」「事件不触发」等问题,别怕,打开控制台(F12)看报错信息,慢慢就能积累经验啦!