DOM

DOM 是 JavaScript 操作网页的接口,全称为“文档对象模型”(Document Object Model)。它的作用是将网页转为一个 JavaScript 对象,从而可以用脚本进行各种操作(比如增删内容)。它只是一个接口规范,可以用各种语言实现。所以严格地说,DOM 不是 JavaScript 语法的一部分,但是 DOM 操作是 JavaScript 最常见的任务,离开了 DOM,JavaScript 就无法控制网页。另一方面,JavaScript 也是最常用于 DOM 操作的语言。

节点

DOM 的最小组成单位叫做节点(node)。文档的树形结构(DOM 树),就是由各种不同类型的节点组成。每个节点可以看作是文档树的一片叶子。节点的类型有七种。

  • Document:整个文档树的顶层节点
  • DocumentType:doctype标签(比如<!DOCTYPE html>)
  • Element:网页的各种HTML标签(比如<body>、<a>等)
  • Attribute:网页元素的属性(比如class="right")
  • Text:标签之间或标签包含的文本
  • Comment:注释
  • DocumentFragment:文档的片段

浏览器提供一个原生的节点对象Node,上面这七种节点都继承了Node,因此具有一些共同的属性和方法。

节点树

所有的节点就好像组成了一棵树,而document节点就代表整个树也就是整个文档。文档的第一层有两个节点,第一个是文档类型节点(<!doctype html>),第二个是 HTML 网页的顶层容器标签<html>。后者构成了树结构的根节点(root node),其他 HTML 标签节点都是它的下级节点。

除了根节点,其他节点都有三种层级关系。

父节点关系(parentNode):直接的那个上级节点

子节点关系(childNodes):直接的下级节点

同级节点关系(sibling):拥有同一个父节点的节点

DOM 提供操作接口,用来获取这三种关系的节点。比如,子节点接口包括firstChild(第一个子节点)和lastChild(最后一个子节点)等属性,同级节点接口包括nextSibling(紧邻在后的那个同级节点)和previousSibling(紧邻在前的那个同级节点)属性。

Node 接口

所有 DOM 节点对象都继承了 Node 接口,拥有一些共同的属性和方法。这是 DOM 操作的基础。

属性

Node.prototype.nodeType

nodeType属性返回一个整数值,表示节点的类型。上面代码中,文档节点的nodeType属性等于常量Node.DOCUMENT_NODE。

document.nodeType // 9

Node 对象定义了几个常量,对应这些类型值。

document.nodeType === Node.DOCUMENT_NODE // true

不同节点的nodeType属性值和对应的常量如下。

  • 文档节点(document):9,对应常量Node.DOCUMENT_NODE
  • 元素节点(element):1,对应常量Node.ELEMENT_NODE
  • 属性节点(attr):2,对应常量Node.ATTRIBUTE_NODE
  • 文本节点(text):3,对应常量Node.TEXT_NODE
  • 文档片断节点(DocumentFragment):11,对应常量Node.DOCUMENT_FRAGMENT_NODE
  • 文档类型节点(DocumentType):10,对应常量Node.DOCUMENT_TYPE_NODE
  • 注释节点(Comment):8,对应常量Node.COMMENT_NODE

确定节点类型时,使用nodeType属性是常用方法。

var node = document.documentElement.firstChild;

if (node.nodeType === Node.ELEMENT_NODE) {

  console.log('该节点是元素节点');

}

Node.prototype.nodeName

nodeName属性返回节点的名称。

// <div id="d1">hello world</div>

var div = document.getElementById('d1');

div.nodeName // "DIV"

不同节点的nodeName属性值如下。

  • 文档节点(document):#document
  • 元素节点(element):大写的标签名
  • 属性节点(attr):属性的名称
  • 文本节点(text):#text
  • 文档片断节点(DocumentFragment):#document-fragment
  • 文档类型节点(DocumentType):文档的类型
  • 注释节点(Comment):#comment

Node.prototype.nodeValue

nodeValue属性返回一个字符串,表示当前节点本身的文本值,该属性可读写。

只有文本节点(text)、注释节点(comment)和属性节点(attr)有文本值,因此这三类节点的nodeValue可以返回结果,其他类型的节点一律返回null。同样的,也只有这三类节点可以设置nodeValue属性的值,其他类型的节点设置无效。

// <div id="d1">hello world</div>

var div = document.getElementById('d1');

div.nodeValue // null

div.firstChild.nodeValue // "hello world"

Node.prototype.textContent

textContent属性返回当前节点和它的所有后代节点的文本内容。

// <div id="divA">This is <span>some</span> text</div>

document.getElementById('divA').textContent

// This is some text

textContent属性自动忽略当前节点内部的 HTML 标签,返回所有文本内容。

该属性是可读写的,设置该属性的值,会用一个新的文本节点,替换所有原来的子节点。它还有一个好处,就是自动对 HTML 标签转义。这很适合用于用户提供的内容。

Node.prototype.baseURI

baseURI属性返回一个字符串,表示当前网页的绝对路径。浏览器根据这个属性,计算网页上的相对路径的 URL。该属性为只读。

// 当前网页的网址为

// http://www.example.com/index.html

document.baseURI

// "http://www.example.com/index.html"

如果无法读到网页的 URL,baseURI属性返回null。

该属性的值一般由当前网址的 URL(即window.location属性)决定,但是可以使用 HTML 的<base>标签,改变该属性的值。

<base href="http://www.example.com/page.html">

设置了以后,baseURI属性就返回<base>标签设置的值。

Node.prototype.nextSibling

Node.nextSibling属性返回紧跟在当前节点后面的第一个同级节点。如果当前节点后面没有同级节点,则返回null。

// HTML 代码如下

// <div id="d1">hello</div><div id="d2">world</div>

var d1 = document.getElementById('d1');

var d2 = document.getElementById('d2');

d1.nextSibling === d2 // true

Node.prototype.parentNode

parentNode属性返回当前节点的父节点。对于一个节点来说,它的父节点只可能是三种类型:元素节点(element)、文档节点(document)和文档片段节点(documentfragment)。

if (node.parentNode) {

  node.parentNode.removeChild(node);

}

上面代码中,通过node.parentNode属性将node节点从文档里面移除。

文档节点(document)和文档片段节点(documentfragment)的父节点都是null。另外,对于那些生成后还没插入 DOM 树的节点,父节点也是null。

Node.prototype.parentElement

parentElement属性返回当前节点的父元素节点。如果当前节点没有父节点,或者父节点类型不是元素节点,则返回null。

if (node.parentElement) {

  node.parentElement.style.color = 'red';

}

上面代码中,父元素节点的样式设定了红色。

Node.prototype.childNodes

childNodes属性返回一个类似数组的对象(NodeList集合),成员包括当前节点的所有子节点。

var children = document.querySelector('ul').childNodes;

上面代码中,children就是ul元素的所有子节点。使用该属性,可以遍历某个节点的所有子节点。

Node.prototype.hasChildNodes()

hasChildNodes方法返回一个布尔值,表示当前节点是否有子节点。

var foo = document.getElementById('foo');

if (foo.hasChildNodes()) {

  foo.removeChild(foo.childNodes[0]);

}

上面代码表示,如果foo节点有子节点,就移除第一个子节点。

Node.prototype.insertBefore()

insertBefore方法用于将某个节点插入父节点内部的指定位置。

var insertedNode = parentNode.insertBefore(newNode, referenceNode);

insertBefore方法接受两个参数,第一个参数是所要插入的节点newNode,第二个参数是父节点parentNode内部的一个子节点referenceNode。newNode将插在referenceNode这个子节点的前面。返回值是插入的新节点newNode。

var p = document.createElement('p');

document.body.insertBefore(p, document.body.firstChild);

Node.prototype.removeChild()

removeChild方法接受一个子节点作为参数,用于从当前节点移除该子节点。返回值是移除的子节点。

var divA = document.getElementById('A');

divA.parentNode.removeChild(divA);

上面代码移除了divA节点。注意,这个方法是在divA的父节点上调用的,不是在divA上调用的。下面是如何移除当前节点的所有子节点。

var element = document.getElementById('top');

while (element.firstChild) {

  element.removeChild(element.firstChild);

}

Node.prototype.replaceChild()

replaceChild方法用于将一个新的节点,替换当前节点的某一个子节点。

var replacedNode = parentNode.replaceChild(newChild, oldChild);

上面代码中,replaceChild方法接受两个参数,第一个参数newChild是用来替换的新节点,第二个参数oldChild是将要替换走的子节点。返回值是替换走的那个节点oldChild。

var divA = document.getElementById('divA');

var newSpan = document.createElement('span');

newSpan.textContent = 'Hello World!';

divA.parentNode.replaceChild(newSpan, divA);

上面代码是如何将指定节点divA替换走。

DOM节点的属性和方法的更多相关文章

  1. HTML DOM对象的属性和方法

    HTML DOM对象的属性和方法 HTML DOM 对象有几种类型: 1.Document 类型 在浏览器中,Document 对象表示整个 HTML 文档. 1.1属性 引用文档的子节点 docum ...

  2. HTML DOM对象的属性和方法介绍(原生JS方法)

    HTML DOM对象的属性和方法介绍 DOM 是 Document Object Model(文档对象模型)的缩写. DOM(文档对象模型)是针对HTML和XML文档的一个API(应用程序编程接口), ...

  3. HTML中DOM对象的属性和方法的层级关系是怎样的?(目录即层次)

    HTML中DOM对象的属性和方法的层级关系是怎样的?(目录即层次) 一.总结 一句话总结:目录就是测试题 1.document取得元素(get element)的方式有哪几种? 解答:四种,分别是id ...

  4. 解决Table不继承父节点的属性的方法

    解决Table不继承父节点的属性的方法 发现table不继承父节点的属性. 解决方法:给html文件加上<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML ...

  5. DOM常用的属性和方法

    之前一直傻傻分不清DOM和JavaScript究竟有什么区别,随着相关工作时间的增长,开始逐渐区分DOM和JavaScript了,最近,也一直在复习有关DOM方面的知识,<JavaScript ...

  6. DOM节点中属性nodeName、nodeType和nodeValue的区别 < Delphi >

    http://msdn.microsoft.com/zh-cn/library/vstudio/hf9hbf87.aspx <?xml version="1.0"?> ...

  7. js Dom对象的属性与方法

    1.对象集合:      (1).all[];      (2).images[];      (3).anchors[];      (4).forms[];      (5).links[];   ...

  8. js dom 的常用属性和方法

    1.对象集合:      (1).all[];      (2).images[];      (3).anchors[];      (4).forms[];      (5).links[];   ...

  9. jQuery框架-2.jQuery操作DOM节点与jQuery.ajax方法

    一.jQuery操作DOM 内部插入操作: append(content|fn):向每个匹配的元素内部追加内容. prepend(content):向每个匹配的元素内部前置内容. 外部插入操作: af ...

随机推荐

  1. Comb使用2

    只需添加如下内容 AndroidManifest中添加如下 不要忘记修改application ID与Comb对应 最好不要采用将combSDK lib文件添加到工程中否则可能连接不了Comb 如果添 ...

  2. 关于求最长子串,使得最大减最小小于k的问题-以POJ4003为例

    问题 给出一个长度为\(n\)的序列\(a[i]\),有\(m\)次询问, 每次给你一个\(k\),让你求一个最长子串\([l,r]\),使得\(max_l^r\{a_i\}-min_l^r\{a_i ...

  3. HDU 6599 I Love Palindrome String (回文树+hash)

    题意 找如下子串的个数: (l,r)是回文串,并且(l,(l+r)/2)也是回文串 思路 本来写了个回文树+dfs+hash,由于用了map所以T了 后来发现既然该子串和该子串的前半部分都是回文串,所 ...

  4. 用Python来自动刷智慧树网站的网课

    学校最近让看什么网课,智慧树网站的,太无聊了,写个脚本刷下,这里是用Python+selenium实现的,也可以用js脚本,更简单,但是我这里刚好最近在学python,就顺便练习下,说下有几个点, 1 ...

  5. FastDFS 原理介绍

    1 功能简介         FastDFS是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储.文件同步.文件访问(文件上传.文件下载)等,解决了大容量存储和负载均衡的问题.特别适 ...

  6. [ERROR]pip insall pyodbc

    - 错误代码如下: pip install pyodbc Looking in indexes: http://172.16.1.250/repository/douban/simple Collec ...

  7. Task.Run()方法总结

    一.从异步方法的声明说起 无返回值的类型异步方法 (1)public async Task MethodName() 带返回值类型的异步方法 (2)public async Task<TResu ...

  8. Python学习小记(5)---Magic Method

    具体见The Python Language Reference 与Attribute相关的有 __get__ __set__ __getattribute__ __getattr__ __setat ...

  9. C语言低级I/O(UNIX接口)

    头文件说明 以下各函数均在<unistd.h>中 flags的各个值定义于<fcntl.h>中 BUFSIZ定义于<stdlib.h>中 (似乎<stdio. ...

  10. 微信小程序组件构建UI界面小练手 —— 表单登录注册微信小程序

    通过微信小程序中丰富的表单组件来完成登录界面.手机快速注册界面.企业用户注册界面的微信小程序设计. 将会用到view视图容器组件.button按钮组件.image图片组件.input输入框组件.che ...