# 找到那个 DOM
# 课程目标
JavaScript 最独特和最有用的能力之一是它能够操纵 DOM,从而实现与您的 HTML 交互以创建交互式用户体验
那么什么是 DOM,我们如何去改变它呢?我们将分几节课学习 DOM 的相关知识,本节我们先学习如何定位 DOM 元素
# DOM 的定义和基本概念
DOM(文档对象模型)是 HTML 和 XML 文档的编程接口。DOM 表示由多层节点构成的文档,通过它开发者可以与页面上的元素进行交互,您可以阅读和更改文本、添加和删页面各个部分
# 选择 DOM 节点
接下我们学习如何定位 DOM 节点,比如你想找到 id 为 header 的<div>
节点,或者找到页面中所有的链接
# document.querySelector
为了能够操作 DOM 中的元素,您必须选择该特定元素,您可以使用以下 document.querySelector 方法从页面中选择单个 DOM 节点:
document.querySelector("CSS 选择器");
querySelector 方法需要一个 CSS 选择器,这与您在 CSS 文件中编写的选择器相同。
如果有多个项目满足您指定的 CSS 选择器,则只返回第一个。
# document.querySelectorAll()
但是,如果您需要查找 1 个以上的元素怎么办?如果需要返回所有匹配的元素"CSS-selector"怎么办?
这种场景下,您需要使用 document.querySelectorAll().
# 常见选择器
让我们来看看一些最常见的选择器:
类型选择器
<form>This is a form</form>
<script>
const form = document.querySelector("form");
</script>
ID 选择器
<div id="sidebar"></div>
<script>
const sidebar = document.querySelector("#sidebar");
</script>
类选择器
<div class="active"></div>
<script>
const item = document.querySelector(".active");
</script>
后代选择器
<ul>
<li></li>
</ul>
<script>
const item = document.querySelector("ul li");
</script>
属性选择器
<input type="text" placeholder="Your name here" disabled />
<script>
document.querySelector("[disabled]");
</script>
更多的 CSS 选择器,请参考Selectors | W3C (opens new window)
如果您想在有趣的游戏中练习 CSS 选择器,请查看flukeout.github.io (opens new window)。
# 其他查找 DOM 节点方法
本课程的建议是,您始终可以使用 querySelector 而不是 getElementById ,而且,因为 querySelector 适用于所有场景,可以避免混淆是否应该添加#。
- Document.getElementById() | MDN (opens new window)
- Document.getElementsByTagName() | MDN (opens new window)
- Document.getElementsByClassName() | MDN (opens new window)
# 节点列表(nodeList)
一个节点列表是 DOM 元素的集合。这意味着它是一个包含多个 DOM 元素的变量。
该节点列表对象类似于数组,但它不是一个数组
# 将节点列表转换为数组
我们知道 NodeList 是类数组 只支持.length, .forEach(),但是如果出于某种原因你想使用.map()或者.filter()呢?
为了能够做到这一点,您必须将 NodeList 转换为一个数组。
const divs = document.querySelectorAll("div"); // NodeList
const items = [...divs]; // Array
如您所见,您可以使用数组展开语法 ( ...)将 NodeList 转换为数组,该语法将 NodeList 的每一项展开为一个新数组。
还有一种方法是可以使用 Array.from()将结点集合转换为数组
const divs = document.querySelectorAll("div"); // NodeList
Array.from(document.body.divs); // Array
# Traversing 遍历 DOM 树
在本课中,您将学习如何遍历 DOM。例如,如何到达父元素以及如何找到与某个选择器匹配的“最近”(搜索父元素)元素。
# 寻找父节点
# element.parentElement
element.parentElement 属性返回当前元素的父元素
# element.closest("CSS 选择器")
# 任务一
请完成下列函数
// 获取当前element元素所有的兄弟节点
function getSiblings(element){
// your implement
}
// 获取当前element元素前一个兄弟节点
function getPrev(element){
// your implement
}
// 获取element元素之前所有的兄弟节点
function getPrevaAll((element){
// your implement
}
// 获取element元素之后第一个兄弟节点
function getNext((element){
// your implement
}
// 获取element元素之后所有的兄弟节点
function getNextAll((element){
// your implement
}
// 获取元素的所有子节点
function getSon(element){
// your implement
}
//获取元素的第一个子节点
function getFirstSon(element){
// your implement
}
/**
* @descriotion 获取element的符号 parent_css_selector 的父元素
* @param {object} element
* @param {String} parent_css_selector 父元素的 css 选择器
*/
function getParent( element,parent_css_selector){
// your implement
}
// 判断element的节点类型,并且返回
function getNodeType(element) {
// your implement
}
// 获取element元素完整的HTML内容
function getHTMLContent(element) {
// your implement
}
// 获取element元素的文本内容
function getText(element) {
// your implement
}
# 任务二
基于我们给出的一个问卷调查页面,使用 querySelector 及 querySelectorAll 来实现如下 DOM 节点搜索要求
在一个单独的窗口中打开 survey.html (opens new window) 页面,并对此页面使用浏览器开发者工具。
- 完成对以下元素的查找
- 带有 id="rate-table" 的表格。
- 带有 name = "select-check: 的 fieldset。
- 表格中的第一个 td (带有 "rate" 字段)
- 表单中的第一个 input。
- 表单中的最后一个 input。
- 获取带有 data-widget-name 特性(attribute)的元素
- 表单中 第二个 name = "dishes" 的单选框
- 表单中 name 含有 pick 字段的元素
- 带有 class = "check" 的元素集合
- 给所有的必填输入框添加一个绿色边框,请您将获取的输入框节点列表表转化为数组
element.style.border = "1px solid green";
- 对页面元素的遍历,编写代码给每一个遍历到的元素添加一个红色背景颜色
element.style.background = "1px solid green";
# 进阶任务
如果你很快就完成上面的任务,可以去 LeetCode 上去多进行一些练习。
# 提交
把你今天觉得做得最好的代码放在 Github 后进行提交。
# 总结
依然把今天的学习用时,收获,问题进行记录。
# 自测问题
- DOM 树的最顶层元素是什么?
- 下面这个脚本会显示什么?
<html>
<body>
<script>
console.log(document.body.lastChild.nodeType);
</script>
</body>
</html>
- document 属于哪一类?它位于 DOM 层次结构(hierarchy)中的什么位置?它继承自 Node 还是 Element,或者可能是 HTMLElement?
- getComputedStyle(elem).width 与 elem.clientWidth 之间有什么不同点?指出至少三种不同点。当然越多越好。