JavaScript 一些 DOM 的知识点
原文链接/)
本来准备把 DOM 的接口都总结一遍,但是我太天真了,DOM 下面的接口太庞大了,总结起来太费时了,所以只将自己平时没注意到的以及常用到的知识记下来了,更详细的 DOM 还是看 MDN 上的资料吧!
Node 接口
Node 是一个接口,该接口由 DOM 中的所有的节点类型实现,即所有节点类型(比如最常见的 Element 类型)都继承自 Node 接口。
本来,节点类型总共有12种,但是随着 DOM4 的出现,有 5 种节点类型被弃用。(详情看这里)
Node 接口的很多属性(比如 childNodes 、lastChild、firstChild、nextSibling、previousSibling)针对的是所有的节点类型,并不只是元素节点。
document.body.childNodes;
在浏览器控制端输入上面的代码,你会看到显示的结果不仅仅有元素节点,还可能有文本节点、注释节点等!
Node.hasChildNodes():检测一个节点下面是否包含一个或多个节点,若是,则返回 true。
Node.contains(otherNode):判断传入的节点是否是调用该方法的节点的后代节点。
Document 类型(文档节点)
JavaScript 通过 Document 类型表示文档。document 对象是 window 对象的一个属性。
一些 document 对象的属性:
document.documentElement // 指向 html 元素
document.head // 指向 head 元素(HTML 5 新增)
document.body // 指向 body 元素
document.characterSet // 取得文档使用的字符集
document.title // 取得或设置文档的标题
document.URL // 取得文档完整的 URL
document.domain // 取得文档所在的域名
Element 类型(元素节点)
Element 类型节点的 nodeType 的值为 1,nodeName 的值为元素的标签名。
-
有关 Element类型节点的特性
获取或设置公认的特性一般直接使用
对应的属性
获取或设置自定义特性,使用
getAttribute()
、setAttribute()
方法根据 HTML5 规范,自定义特性应该加上
data-
前缀以便验证
// HTML 代码
<div id="container" class="class1 class2" title="titleValue">
Some text
<div>
// js 代码,运行于浏览器控制端
var ele = document.getElementById("container");
ele.id; // "container"
ele["id"]; // "container"
ele.className; // "class1 class2"
ele.title; // "titleValue"
ele.className += " class3"; // 更改 class 的值
ele.className; // "class1 class2 class3"
// 利用 setAttribute() 可以添加元素不存在的特性
ele.setAttribute("data-test","just test"); // 添加自定义特性
ele["data-test"]; // undefined,不能直接访问自定义特性
ele.getAttribute("data-test"); // "just test"
ele.removeAttribute("class"); // 删除 class 特性
ele.className; // "",一个空字符串
classList 属性
这个属性是 HTML5 中新增的用来操作元素类名的属性。它比 className 属性使用起来更方便。这个属性返回的是一个新集合类型 DOMTokenList 的实例,它也是一个类数组对象。
<div id="container" class="class1 class2"><div>
var ele = document.getElementById("container");
ele.classList; // ["class1", "class2"]
ele.classList[0]; // "class1" string 类型
ele.classList.length; // 2
ele.classList.add("class3"); // 添加新类名
ele.classList.remove("class1"); // 删除类名
ele.classList; // ["class2", "class3"]
// contains() 用来检测是否某个类名
ele.classList.contains("class1"); // false
ele.classList.contains("class2"); // true
// toggle() 用来交替删除添加某个类名
ele.classList.toggle("class4"); // 不存在,则添加
ele.classList; // ["class2", "class3", "class4"]
ele.classList.toggle("class4"); // 存在,则删除
ele.classList; // ["class2", "class3"]
attributes 属性:返回一个
NamedNodeMap
类数组对象,它不能使用数组的方法。
一般不使用这个属性,除非用来遍历元素的特性。
// 继续上面的代码
ele.attributes; // NamedNodeMap {0: id, 1: title, 2: data-test, length: 3}
ele.attributes[0].nodeName; // "id"
ele.attributes[0].nodeValue; // "container"
document.createElement():创建新元素节点
var div = document.createElement("div");
console.log(div); // <div></div>
console.log(typeof div); // object
div.id = "container";
div.className = "a b c";
console.log(div); // <div id="container" class="a b c"></div>
元素遍历
我们前面说过,某个元素节点的 childNodes 属性返回的集合可能会包含注释节点、文本节点等我们一般不会去操作的节点,我们想要的只是元素节点。所以我们可以用下面的方法来达到我们的目的:
// 原理:通过 if 条件语句过滤掉不是元素节点的其它节点
var ele = document.getElementById("container");
var len = ele.childNodes.length;
for(let i = 0; i < len; i++){
if(ele.childNodes[i].nodeType === 1){
// 执行一些操作
ele.childNodes[i].style.color = "green";
}
}
很幸运,现在,W3C 已经帮我们搞出了一些新的属性来专门操作元素节点。
Element.children:返回一个该元素下所有子元素节点的集合
Element.firstElementChild:返回第一个子元素节点
Element.lastElementChild:返回最后一个子元素节点
Element.previousElementSibling:返回前一个同辈元素节点
Element.nextElementSibling:返回后一个同辈元素节点
-
插入标记
innerHTML:返回或更改调用它的节点的所有子节点(包括注释节点、文本节点等)
outerHTML:返回或更改调用它的元素以及这个元素所有的子节点
上面两种属性返回的都是字符串
-
element.insertAdjacentHTML(position, text):将指定的文本解析为 HTML 或 XML,然后将结果节点插入到指定的位置上
position 是相对于 element 元素的位置,并且它有四个值
beforebegin:在 element 元素之前插入一个紧邻的同辈元素
afterbegin:在 element 元素的第一个子节点之前插入
beforeend:在 element 元素的最后一个节点之后插入
afterend:在 element 元素之后插入一个紧邻的同辈元素
Text 类型(文本节点)
Text 类型的节点(文本节点)的 nodeType 的值为 3。
document.createTextNode("文本内容"):创建新文本节点
规范化文本节点
DOM 文档中存在相邻的文本节点很容易导致混乱,因为分不清哪个文本节点表示哪个字符串。所以在 Node 接口中定义了一个 normalize()
方法,用来将当前节点和它的后代节点规范化。在一个"规范化"后的DOM树中,不存在一个空的文本节点,或者两个相邻的文本节点。
var ele = document.createElement("div");
var textNode = document.createTextNode("Hello ");
ele.appendChild(textNode);
var anotherTextNode = document.createTextNode("world!");
ele.appendChild(anotherTextNode);
document.body.appendChild(ele);
console.log(ele.childNodes.length); // 2
ele.normalize(); // 规范化文本节点
console.log(ele.childNodes.length); // 1
innerText 属性:取得或更改操作元素包含的所有文本内容
Comment 类型(注释节点)
一般不会去操作注释节点!
<div id="test"><!-- A comment --></div>
// 注释节点是 div 元素的一个子节点
document.createComment():创建一个注释节点
选择符 API
Selector API 是由 W3C 发起制定的一个标准,致力于让浏览器原生 JavaScript 支持 CSS 查询。
Selectors API Level 1 的核心是两个方法:
querySelector()
和querySelectorAll()
。
// selectors 是一个 CSS 选择器字符串
// 从整个文档开始查找
Document.querySelector(selectors)
Document.querySelectorAll(selectors)
// 从 Element 元素的后代元素开始查找
Element.querySelector(selectors)
Element.querySelectorAll(selectors)
文档模式(document mode)
Doctype 是 Document Type (文档类型)的简写,用来说明你用的XHTML或者HTML是什么版本。它的作用是告知浏览器的解析器,用什么文档类型规范来解析这个文档。
文档模式用于指定IE的页面排版引擎(Trident)以哪个版本的方式来解析并渲染网页代码
-
document.compatMode:检测当前文档的渲染模式
若值为 BackCompat,则为混杂模式
若值为 CSS1Compat,则为标准规范模式
document.documentMode:检测 IE 浏览器是在哪个浏览器模式下(这个属性只适用于 IE 浏览器)
DOM2 样式
HTMLElement.style:返回一个 CSSStyleDeclaration 对象,表示元素的内嵌 style 属性。
这个属性的返回值只包含了在元素内嵌 style 属性上声明的的 CSS 属性,而不包括来自其他地方声明的样式(比如 head 部分声明的 CSS 属性)。
由于 style 属性的优先级和通过 style 设置元素的内联样式是一样的,并且在css层级样式中拥有最高优先级,因此在为特定的元素设置样式时很有用。
// 为元素添加 2 个内嵌的 CSS 规则
var ele = document.getElementById("container");
// 方法一
ele.setAttribute("style","font-size:2em;color:green");
// 方法二
ele.style.cssText = "font-size:2em;color:green";
// 方法三
var sty = ele.style;
sty.fontSize = "2em";
sty.color = "green";
要获取一个元素的所有 CSS 属性,你应该使用 window.getComputedStyle()
// 单纯地调用这个方法,会和上面的 style 属性一样返回一个 CSSStyleDeclaration 对象
window.getComputedStyle(ele);
// 该方法返回经过叠加计算后的元素的实际样式
window.getComputedStyle(ele).fontSize;
window.getComputedStyle(ele).color;
document.styleSheets:只读,返回一个由 StyleSheet 对象组成的 StyleSheetList,每个 StyleSheet 对象都是文档中链接或嵌入的样式表(即内联样式和外联样式,不包括嵌在元素里的样式)。
// 获取当前文档中样式表的数量
document.styleSheets.length;
// 禁用第一个样式表
document.styleSheets[0].disabled = true;
DOM2 遍历
DOM2 中定义了两个用于辅助完成顺序遍历 DOM 结构的类型:NodeIterator 和 TreeWalker。
document.createNodeIterator():返回一个 NodeIterator 对象
document.createTreeWalker():返回一个 TreeWalker 对象
这里只简单提一下这两个方法,因为暂时还没用过,所以先不展开了,以后用了再补。
DOM2 范围(range)
Range 对象 表示一个包含节点和部分文本节点的文档片段
document.createRange():返回一个 Range 对象
这个也是简单提一下,以后用到了再补。
参考资料
【书】《JavaScript 高级程序设计(第三版)》
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。