DOM《Document节点》

277 阅读8分钟

概述

  • document节点对象代表整个文档,每张网页都有自己的document对象。只要浏览器开始载入HTML文档,该对象就存在了,可以直接使用。
  • document对象继承了EventTarget接口和Node接口,并且混入了ParentNode接口,意味着这些接口的方法都可以使用。

获取document

  • 正常网页: 直接使用documentwindow.document
  • 获取iframe里的网页:使用iframe节点的contentDocument属性。
  • Ajax返回的网页:使用XMLHttpRequest对象的responseXML属性。
  • 内部节点:使用节点ownerDocument属性。

快捷方式属性

  • 指向文档内部的某个节点的快捷方式。

defaultView

  • 返回document对象所属的window对象,如果当前文档不属于window,则返回null

doctype

  • 返回文档类型,一般写成<!DOCTYPE html>,如果网页没有声明则该属性返回null
let doctype = document.doctype;
doctype // <!DOCTYPE html>

documentElement

  • 返回当前文档的根元素节点。一般是返回<html>节点。

body

  • 返回<body>节点。

head

  • 返回<head>节点。

scrollingElement

  • 返回文档的滚动元素(当文档整体滚动时,到底是哪个元素在滚动)。标准模式下,返回的是<html>节点。兼容模式下,返回的是<body>元素,如果该元素不存在,返回null

activeElement

  • 返回获得当前焦点的DOM元素。返回的一般是<input>、<textarea>、<select>等表单元素。如果没有焦点元素,返回<body>null

fullscreenElement

  • 返回当前以全屏状态展示的DOM元素。如果不是全屏状态则返回null

节点集合属性

  • 以下属性除了styleSheet都返回一个HTMLCollection实例,如果节点有idname属性,则可以直接通过id/name引用。

links

  • 返回当前文档所有设定了href属性的<a><area>节点。

forms

  • 返回所有<form>表单节点。

images

  • 返回所有<img>图片节点。

embeds、plugins

  • 返回所有<embed>节点。

scripts

  • 返回所有<sctipt>节点。

styleSheet

  • 返回网页内嵌或引入的CSS样式表集合,返回的是styleSheetList实例。

静态信息属性

documentURI

  • 返回一个字符串,表示当前文档的网址。此属性继承自Document接口,可用于所有文档。
document.documentURI // 'file:///C:/Users/zhongboyang/Desktop/test.html'

URL

  • 返回一个字符串,表示当前文档的网址。此属性继承自HTMLDocument接口,只能用于HTML文档。

domain

  • 返回当前文档的域名,不包含协议和端口。基本是一个只读属性,但可以修改二级域名

location

  • 返回浏览器提供的location原生对象,可以操作URL。

lastModified

  • 返回一个字符串,表示当前文档最后修改的时间。
document.lastModified // '02/25/2024 16:58:08'

title

  • 返回当前文档的标题,默认返回<title>节点的值。可读写。
document.title  // 'Document'

document.title = '新标题';
document.title  // '新标题'

characterSet

  • 返回当前文档的编码,比如UTF-8等。

referrer

  • 返回一个字符串,表示当前文档的访问者来自哪里。如果无法获取来源,或者用户直接键入网址而不是从其他网页点击进入,document.referrer返回一个空字符串。
  • document.referrer的值,总是与 HTTP 头信息的Referer字段保持一致。但是,此属性的拼写有两个r,而头信息的Referer字段只有一个r

dir

  • 返回一个字符串,表示文字方向。只有两个可能的值:rtl(从右到左);ltr(从左到右)。

compatMode

  • 返回浏览器处理文档的模式,只有两个可能的值:BackCompat(向后兼容模式);CSS1Compat(严格模式)。如果文档第一行设置了明确的DOCTYPE(比如<!doctype html>),则此属性的值为CSS1Compat

状态属性

hidden

  • 返回一个布尔值,表示当前页面是否可见。如果窗口最小化或浏览器切换了tab导致页面不可见,值为true

visibilityState

  • 返回文档的可见状态:

    • visible:页面可见。注意,页面可能是部分可见,即不是焦点窗口,前面被其他窗口部分挡住了。
    • hidden:页面不可见,有可能窗口最小化,或者浏览器切换到了另一个 Tab。
    • prerender:页面处于正在渲染状态,对于用户来说,该页面不可见。
    • unloaded:页面从内存里面卸载了。

readyState

  • 返回当前文档的状态:

    • loading:加载HTML代码阶段(尚未解析完成)。
    • interactive:加载外部资源阶段。
    • complete:加载完成。
  • 属性变化过程:

    • 浏览器开始解析HTML文档,状态为loading
    • 浏览器遇到HTML文档中的<script>元素,并且没有设置asyncdefer属性,就暂停解析,开始执行JS,此时状态还是loading
    • HTML文档解析完成,状态为interactive
    • 浏览器等待图片、样式表、字体文件等外部资源加载完成后,状态为complete

cookie

  • 用来操作浏览器 Cookie。

designMode

  • 控制当前文档是否可编辑,该属性只有onoff,默认为off。一旦设为on,用户就可以编辑整个文档的内容。

currentScript

  • 只用在<script>元素的内嵌脚本或加载的外部脚本之中,返回当前脚本所在的那个DOM节点。
<script id="foo">
  console.log(document.currentScript === document.getElementById('foo')); // true
</script>

implementtation

  • 返回一个DOMImplementation对象,该对象有三个方法,主要用于创建独立于当前文档的新的Document对象。

    • DOMImplementation.createDocument():创建一个 XML 文档。
    • DOMImplementation.createHTMLDocument():创建一个 HTML 文档。
    • DOMImplementation.createDocumentType():创建一个 DocumentType 对象。

方法

open()、close()

  • open()方法清除当前文档所有内容,使得文档处于可写状态,供document.write方法写入内容。close()方法用来关闭document.open()打开的文档。
document.open();
document.write('hello world');
document.close();

write()、writeln()

  • 用于向当前文档写入内容。如果页面已经解析完成(DOMContentLoaded事件发生之后),再调用write方法,它会先调用open方法,擦除当前文档所有内容,然后再写入。
  • writeln()write()完全一致,除了会在输入内容的尾部添加换行符。

querySelector()

接受一个CSS选择器作为参数,返回匹配该选择器的元素节点。如果有多个节点满足匹配条件则返回第一个匹配的节点。如果没有匹配的则返回null

  • 支持复杂的CSS选择器,但不支持伪元素和伪类选择器
var el1 = document.querySelector('.myclass'); // 匹配class属性为myclass的元素
var matches = document.querySelectorAll('div.note, div.alert');  // 返回class属性是note或alert的div元素

querySelectorAll()

  • querySelector()用法一致,区别是此方法返回一个NodeList类数组。

getElementsByTagName()

  • 根据HTML标签名匹配符合条件的元素。返回一个HTMLCollection实例。
var paras = document.getElementsByTagName('p');

getElementsByClassName()

  • 根据class名字匹配符合的元素,返回一个HTMLCollection实例。
var elements = document.getElementsByClassName('foo bar');

getElementsByName()

  • 用于选择拥有name属性的HTML元素,返回一个NodeList实例。
<form name="x"></form>

var forms = document.getElementsByName('x');

getElementById()

  • 返回匹配指定id属性的元素节点。如果未匹配到返回null
var elem = document.getElementById('box');

elementFromPoint()

  • 返回位于页面指定位置最上层的元素节点。两个参数,依次是相对于当前视口左上角的横坐标和纵坐标,单位是像素。如果位于该位置的 HTML 元素不可返回(比如文本框的滚动条),则返回它的父元素(比如文本框)。如果坐标值无意义(比如负值或超过视口大小),则返回null
var element = document.elementFromPoint(50, 50);

elementsFromPoint()

  • elementFromPoint()功能一致,区别是返回一个数组,成员是位于指定坐标的所有元素。

createElement()

  • 生成元素节点并返回该节点,参数是标签名。可以自定义标签名
var newDiv = document.createElement('div');

var newTag = document.createElement('aaa'); // <aaa></aaa>

createTextNode()

  • 生成文本节点并返回该节点(Text实例),参数是文本节点的内容。
var newContent = document.createTextNode('Hello');

createAttribute()

  • 生成一个新的属性节点(Attr实例)并返回它。
var a = document.createAttribute('long');
a.value = '300';
a // long="300"

createComment()

  • 生成一个新的注释节点(Comment实例)并返回该节点。
var comment = document.createComment("123456");
comment // <!--123456-->

createDocumentFragment()

  • 生成一个空的文档片段节点(DocumentFragment实例)并返回该节点。
  • DocumentFragment是一个存在于内存中的DOM片段,不属于当前文档。常常用来生成一段较复杂的DOM结构,然后再插入当前文档。好处是对DocumentFragment的任何改动都不会引发网页的重排或重绘,比直接修改DOM性能更好。
// <ul>中插入4个<li>
var docfrag = document.createDocumentFragment();

[1, 2, 3, 4].forEach(function (e) {
  var li = document.createElement('li');
  li.textContent = e;
  docfrag.appendChild(li);
});

var element  = document.getElementById('ul');
element.appendChild(docfrag);

createEvent()

  • 生成一个事件对象(Event实例),参数是事件类型,该对象可以被element.dispatchEvent方法使用。
// 新建了一个名为`build`的事件实例,然后触发该事件。
var event = document.createEvent('Event');

event.initEvent('build', true, true);

document.addEventListener('build', function (e) {
  console.log(e.type); // "build"
}, false);
document.dispatchEvent(event);

hasFocus()

  • 返回一个布尔值,表示当前文档之中是否有元素被激活或获得焦点。有焦点的文档必定被激活,反之不成立。
var focused = document.hasFocus();

adoptNode()

  • 将某个节点及其子节点从原来所在的文档或DocumentFragment中移除,并返回该节点。
// 可采集iframe 中的第一个 H1 元素
const frame = document.getElementById("myFrame");
const h1 = frame.contentWindow.document.getElementsByTagName("H1")[0];
const node = document.adoptNode(h1);  // 将iframe中的 h1移除并返回
document.body.appendChild(node);      // 添加到当前文档中

importNode()

  • 从原来所在的文档或DocumentFragment中拷贝某个节点及其子节点,被拷贝的节点不会被移除。第二个参数表示对外部节点是深拷贝还是浅拷贝。默认为浅拷贝(false)。
var iframe = document.getElementsByTagName('iframe')[0];
var oldNode = iframe.contentWindow.document.getElementById('myNode');
var newNode = document.importNode(oldNode, true);
document.getElementById("container").appendChild(newNode);

createNodeIterator()

  • 返回一个子节点遍历器(NodeFilter实例)。参数一为所要遍历的根节点,参数二为所要遍历的节点类型。

  • 节点类型:

    • 所有节点: NodeFilter.SHOW_ALL(默认)
    • 元素节点:NodeFilter.SHOW_ELEMENT
    • 文本节点:NodeFilter.SHOW_TEXT
    • 注释节点:NodeFilter.SHOW_COMMENT
// 创建一个body子节点遍历器
var nodeIterator = document.createNodeIterator(document.body);
var pars = [];
var currentNode;

// 每次读取下一个节点
while (currentNode = nodeIterator.nextNode()) {
  pars.push(currentNode);
}
pars[0] === document.body // true 遍历器的第一个节点总是根节点

createTreeWalker()

  • 返回一个DOM的子树遍历器(TreeWalker实例),参数与createNodeIterator一致。
// 遍历<body>节点下属的所有元素节点,将它们插入`nodeList`数组
var treeWalker = document.createTreeWalker(
  document.body,
  NodeFilter.SHOW_ELEMENT
);

var nodeList = [];

while(treeWalker.nextNode()) {
  nodeList.push(treeWalker.currentNode);
}