JavaScriptのNode节点

DOM的最小组成单位叫做节点(node),一个文档的树形结构(DOM树),就是由各种不同的类型的节点组成.

对于HTML文档,节点主要有以下六种类型:Document节点、DocumentType节点、Element节点、Attribute节点、Text节点和DocumentFragment节点。

节点 名称 含义
Document 文档节点 整个文档(window.document)
DocumentType 文档类型节点 文档的类型(比如<!DOCTYPE html>)
Element 元素节点 HTML元素(比如<body>、<a>等)
Attribute 属性节点 HTML元素的属性(比如class=”right”)
Text 文本节点 HTML文档中出现的文本
DocumentFragment 文档碎片节点 文档的片段

浏览器原生提供一个Node对象,上表所有类型的节点都是Node对象派生出来的。也就是说,它们都继承了Node的属性和方法。

Node节点的属性

nodeName,nodeType

nodeName属性返回节点的名称,nodeType属性返回节点的常数型.

类型 nodeName nodeType
DOCUMENT_NODE document 9
ELEMENT_NODE 大写的HTML元素名 1
ATTRIBUTE_NODE 等同于Attr.name 2
TEXT_NODE text 3
DOCUMENT_FRAGMENT_NODE document-fragment 11
DOCUMENT_TYPE_NODE 等同于DocumentType.name 10
document.querySelector('a').nodeType ===1
//true
document.querySelector('a').nodeType === Node.ELEMENT_NODE  //true
两者等价

这些属性返回当前节点的相关节点ownerDocument, nexSibling, previousSibling, parentNode, parentElement.

(1)ownerDocument:返回当前节点所在的顶层文档对象,即document对象
var d = p.ownerDocument;
d === document  //true
(2)nextSibling:返回紧跟在当前节点后面的第一个同级节点.同一级可能是不同的标签也是可以实现的.

(3)previousSibling:返回当前节点前面的、距离最近的同一级节点.

(4)parentNode:返回当前节点的父节点.对一个节点来说,它的父节点只可能有三种类型:element节点、document节点和documentfragment节点
如何从父节点移除指定节点
if (node.parentNode) {
    node.parentNode.removeChild(node);
}
(5)parentElement:返回当前节点的父Element节点.
设置执行节点的父element节点的css属性
if(node.parentElement) {
    node.parentElement.style.color = "red";
}

textContent、nodeValue:返回当前节点的内容

(1):textContent:返回当前节点和它的所有后代节点的文本内容
//<div id="divA">This is <span>some</span> text </div>
document.getElementById("divA").textContent;
//This is some text

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


IE中,所有Element节点都有一个innerText属性,它与textContent属性基本相同,但有几点区别

1.innerText受CSS影响,textcontent不受。比如,如果CSS规则隐藏(hidden)了某段文本,innerText就不会返回这段文本,textcontent则照样返回。
2. innerText返回的文本,会过滤掉空格、换行和回车键,textcontent则不会。
3. innerText属性不是DOM标准的一部分,Firefox浏览器甚至没有部署这个属性,而textcontent是DOM标准的一部分。

nodeValue:返回或设置当前节点的值,格式为字符串.该属性只对Text节点、Comment节点、XML文档的CDATA节点有效,其他一律返回null

childNodes、firstNode、lastChild,返回当前节点的子节点

(1)childNodes:返回一个NodeList集合,包含当前节点的所有子节点.
(2)firstNode:返回当前节点的第一个子节点
(3)lastChild:返回当前节点的最后一个子节点

baseURI:返回一个字符串,由当前网页的协议、域名和所在的目录组成,表示当前网页的绝对路径.

通常情况下,该属性由当前网址的URL(即window.location属性)决定

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

Node节点的方法

appendChild(),hasChildNodes(),方法与子节点有关

(1)appendChild():接受一个节点对象作为参数,将其作为最后一个子节点,插入当前节点.
var p = document.createElement("p");
document.body.appendChild(p);
(2)hasChildNodes():结合firstChild属性和NextSibling属性,可以遍历当前节点的所有后代节点.

cloneNode(),insertBefore(),removeChild(),replaceChild():与节点的操作有关

(1):cloneNode():克隆一个节点,接受一个布尔值作为参数,表示是否克隆子节点,默认不克隆
var cloneUL = document.querySelector('ul').cloneNode(true);
(2)insertBefore():将某个节点插入当前节点的指定位置.它接受两个参数,第一个参数是所要插入的节点,第二个参数是当前节点的一个子节点,新的节点将插在这个节点的前面
(3)removeChild():接受一个子节点作为参数,用于从当前节点移除该节点.它返回被移除的节点.
var elemnt = document.getElementById("top");
while (element.firstChild) {
    elemnt.removeChild(element.firstChild);
}

//移除所有子节点
(4)replaceChild():将一个新的节点,替换当前节点的某一个子节点.它接受两个参数,第一个参数是用来替换的新节点,第二个参数将要被替换走的子节点。
replacedNode = parentNode.replaceChild(newChild, oldChild);

contains(), compareDocumentPosition(), isEqualNode() .用于节点的相互比较

(1)contains():接受一个节点作为参数,返回一个布尔值,表示参数节点是否为当前节点的后代节点。
document.body.contains(node)
(2)compareDocumentPosition():与contains方法完全一致,返回一个7个比特位的二进制值,表示参数节点与当前节点的关系。
二进制值 数值 含义
000000 0 两个节点相同
000001 1 两个节点不在同一个文档(即有一个节点不在当前文档)
000010 2 参数节点在当前节点的前面
000100 4 参数节点在当前节点的后面
001000 8 参数节点包含当前节点
010000 16 当前节点包含参数节点
100000 32 浏览器的私有用途

(3)isEqualNode():返回一个布尔值,用于检测两个节点是否相等.
vartargerE1 = document.getElementById("targetE1");
var firstDiv = document.getElementsByTagName("div")[0];

targetE1.isEqualNode(firstDiv)

normalize:用于清理当前节点内部的所有Text节点。它会去除空的文本节点,并且将毗邻的文本节点合并成一个。

var wrapper = document.createElement("div");

wrapper.appendChild(document.createTextNode("Part 1 "));
wrapper.appendChild(document.createTextNode("Part 2 "));

wrapper.childNodes.length // 2

wrapper.normalize();

wrapper.childNodes.length // 1

NodeList接口, HTMLCollection接口

节点对象都是单个节点,但是有时会需要一种数据结构,能够容纳多个节点。DOM提供两种接口,用于部署这种节点的集合:NodeList接口和HTMLCollection接口。

NodeList接口

NodeList接口有时返回一个动态集合,有时返回一个静态集合。

var parent = document.getElementById('parent');
parent.childNodes.length // 2
parent.appendChild(document.createElement('div'));
parent.childNodes.length // 3

document.querySelectorAll方法返回的是一个静态,DOM内部的变化,并不会实时反映在该方法的返回结果之中。

NodeList接口提供length属性和数字索引,因此可以像数组那样,使用数字索引取出每个节点,但是它本身并不是数组,不能使用pop或push之类数组特有的方法。

// 数组的继承链
myArray --> Array.prototype --> Object.prototype --> null

// NodeList的继承链
myNodeList --> NodeList.prototype --> Object.prototype --> null

从上面的继承链可以看到,NodeList接口对象并不继承Array.prototype,因此不具有数组接口提供的方法。如果要在NodeList接口使用数组方法,可以将NodeList接口对象转为真正的数组。

var div_list = document.querySelectorAll('div');
var div_array = Array.prototype.slice.call(div_list);

遍历NodeList接口对象的首选方法,还是使用for循环。

for (var i = 0; i < myNodeList.length; ++i) {
  var item = myNodeList[i];
}

NodeList接口提供item方法,接受一个数字索引作为参数,返回该索引对应的成员。如果取不到成员,或者索引不合法,则返回null。

nodeItem = nodeList.item(index)

// 实例
var divs = document.getElementsByTagName("div");
var secondDiv = divs.item(1);

HTMLCollection接口

HTMLCollection接口与NodeList接口类似,也是节点的集合,但是集合成员都是Element节点.document.links、docuement.forms、document.images等属性,返回的都是HTMLCollection接口对象。

item方法根据成员的位置参数(从0开始),返回该成员。如果取不到成员或数字索引不合法,则返回null。

namedItem方法根据成员的ID属性或name属性,返回该成员。如果没有对应的成员,则返回null。

ParentNode接口,ChildNode接口

不同的节点除了继承Node接口以外,还会继承其他接口。ParentNode接口用于获取当前节点的Element子节点,ChildNode接口用于处理当前节点的子节点(包含但不限于Element子节点)。

ParentNode接口

用于获取Element子节点。Element节点、Document节点和DocumentFragment节点,部署了ParentNode接口。凡是这三类节点,都具有以下四个属性,用于获取Element子节点。

(1)children

children属性返回一个动态的HTMLCollection集合,由当前节点的所有Element子节点组成。

(2)firstElementChild
(3)lastElementChild
(4)childElementCount:返回当前节点的所有Element子节点的数目。

ChildNode接口

用于处理子节点(包含但不限于Element子节点)。Element节点、DocumentType节点和CharacterData接口,部署了ChildNode接口。凡是这三类节点(接口),都可以使用下面四个方法。但是现实的情况是,除了第一个remove方法,目前没有浏览器支持后面三个方法。

(1):remove 移除当前节点
(2)before(), (3)after , (4)replaceWith()

html元素

html元素是网页的根元素,document.documentElement就指向这个元素

(1)clientWidth属性, clientHeight属性

返回视口(viewport)的大小
innerWidth和innerHeight包括滚动条的高度和宽度,二client不将滚动条计算在内

(2)offsetWidth属性,offsetHeight属性

返回html元素的宽度和高度,即网页的总宽度和总高度


dataset属性

用于操作HTML标签元素的data-*属性

tabindex属性

用来指定,当前HTML元素节点是否被tab键遍历,以及遍历的优先级。

var b1 = document.getElementById("button1");

b1.tabIndex = 1;

如果 tabindex = -1 ,tab键跳过当前元素。

如果 tabindex = 0 ,表示tab键将遍历当前元素。如果一个元素没有设置tabindex,默认值就是0。

如果 tabindex 大于0,表示tab键优先遍历。值越大,就表示优先级越大。


页面位置相关属性

offsetParent属性,offsetTop属性和offsetLeft属性
  • offsetParent:当前HTML元素的最靠近的、并且CSS的position属性不等于static的父元素。
  • offsetTop:当前HTML元素左上角相对于offsetParent的垂直位移。
  • offsetLeft:当前HTML元素左上角相对于offsetParent的水平位移。

style属性

用来读写页面元素的行内CSS属性


Element对象方法

(1)选择子元素的方法

Element对象也部署了document对象的4个选择子元素的方法,而且用法完全一样。

  • querySelector方法
  • querySelectorAll方法
  • getElementsByTagName方法
  • getElementsByClassName方法
(2)elementFromPoint方法

用于选择在指定座标的最上层的Element对象

(3)HTML元素的属性相关方法
  • hasAttribute():返回一个布尔值,表示Element对象是否有该属性。
  • getAttribute()
  • setAttribute()
  • removeAttribute()
(4)matchesSelector方法

返回一个布尔值,表示Element对象是否符合某个CSS选择器

document.querySelector('li').matchesSelector('li:first-child')
(5)focus方法

用于将当前页面的焦点,转移到指定元素上

document.getElementById('my-span').focus();

table元素

表格有一些特殊的DOM操作方法。

  • insertRow():在指定位置插入一个新行(tr)。
  • deleteRow():在指定位置删除一行(tr)。
  • insertCell():在指定位置插入一个单元格(td)。
  • deleteCell():在指定位置删除一个单元格(td)。
  • createCaption():插入标题。
  • deleteCaption():删除标题。
  • createTHead():插入表头。
  • deleteTHead():删除表头。

table元素有以下属性:

  • caption:标题。
  • tHead:表头。
  • tFoot:表尾。
  • rows:行元素对象,该属性只读。
  • rows.cells:每一行的单元格对象,该属性只读。
  • tBodies:表体,该属性只读。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章