DOM知识点总结

什么是DOM

DOM(文档对象模型)是针对HTML和XML的文档的一个API ,DOM描绘了一个层次化的节点树,允许开发人员添加,修改和删除页面中的一部分。

节点类型

DOM1定义了一个Node接口,该接口由DOM中所有的节点类型实现。节点类型由在Node类型中定义的12个数值常量来表示,任何节点类型必居其一:

  • Node.ELEMENT_NODE(1)
  • Node.ATTRIBUTE_NODE(2)
  • Node.TEXT_NODE(3)
  • Node.CDATA_SECTION_NODE(4)
  • Node.ENTITY_REFRENCE_NODE(5)
  • Node.ENTITY_NODE(6)
  • Node.PROCESSION_INSTRUCTION_NODE(7)
  • Node.COMMENT_NODE(8)
  • Node.DOCUMENT_NODE(9)
  • Node.DOCUMENT_TYPE_NODE(10)
  • Node.DOCUMENT_FRAGMENT_NODE(11)
  • Node.NOTATION_NODE(12)

每个节点都有一个nodeType属性,通过比较上面这些常量可以很容易知道节点的类型,但是由于IE浏览器并没有公开Node类型,因此最好还是将nodeType与数字值进行比较

if (someNode.nodeType === 1) {
  console.log('this is a element');
}

节点属性

JavaScript中的每个节点都继承自Node类型,因此每个节点都有相同的基本属性和方法。

nodeName和nodeValue属性

可以使用nodeNamenodeValue来了解节点的具体信息。这两个属性值完全取决于节点的类型,在使用之前最好先像下面这样进行检测一下:

if (someNode.nodeType === 1) {
  let value = someNode.nodeName; // nodeName的值是元素的标签名
}

像上面这样,首先检测这个节点的类型,看它是不是一个元素,如果是便获取它的nodeName的值,对于元素类型的节点来说,nodeName的值是这个元素的标签名,而nodeValue的值始终是null

childNodes属性

每个节点都有一个childNodes属性,这个属性里面保存着一个NodeList对象NodeList是一个类数组的对象,里面保存着一组有序的节点。可以通过位置来访问这些节点。这个NodeList虽然也有length属性,但是它并不是Array的实例。NodeList的独特之处在于,它实际上是根据当前DOM结构进行查询的结果。因此DOM结构的变化可以在NodeList中反应出来。下面的例子展示了如何获取NodeList中保存的节点:

let firstChild = someNode,childNodes[0];
let secondChild = someNode.childNodes.item(1);
let count = someNode.childNodes.length;

在访问NodeList中保存的节点时,使用[]或者是item()方法都可以,由于使用[]比较像数组的语法,所以更受青睐。

previousSibling和nextSibling属性

childNodes列表中的每个节点相互之间都是同胞节点。通过使用列表中的previousSiblingnextSibling属性可以访问列表中的其他节点。列表中的第一个节点的previousSibling属性值是null,最后一个节点的nextSibling属性值为null。如下所示:

if (someNode.nextSibling === null ) {
  console.log('this.is the last node');
} else if (someNode.previousSibling === null) {
  console.log('this is the first node');
}

parentNode,firstChild,lastChild属性

每个节点都有一个parentNode属性,这个属性指向文档树中的父节点。包含着childNodes中的所有节点都有一个相同的父节点,因此它们的parentNode属性指向同一个节点。父节点与childNodes列表中的第一个节点最后一个节点也有存在着特殊关系。父节点的firstChildlastChild属性分别指向列表中的第一个子节点最后一个字节点。其中someNode.fristNode的值等于someNode.childNodes[0]。而someNode.lastNode的值等于someNode.childNodes[someNode.childNodes.length - 1]的值。在只有一个子节点的情况下,firstChild和lastChild属性指向同一个值在没有子节点的情况下,firstChild和lastChild属性值都为null。下图向我们表明了各节点之间的关系:
在这里插入图片描述

ownerDocument属性

所有节点拥有的最后一个属性是ownerDocument属性,该属性指向表示整个文档的文档节点

hasChildNodes()方法

hasChildNodes()方法在节点拥有子节点的情况下会返回true,这比查询childNodes的length属性更方便快捷。

操作节点

因为关系指针都是只读的,所以DOM提供了一些操作节点的方法。

appendChild()

appendChild()用于向childNodes列表的末尾添加一个节点。添加成功后,childNodes列表中新增的节点,父节点以及以前的最后一个节点的关系指针都会进行更新,更新完成后,appendChild()返回新增的节点

let returnedNode = someNode.appendChild(newNode);
console.log(returnedNode === newNode);// true
console.log(someNode.lastChild === newNode); // true

如果appendChild()操作的节点本身是文档树的一部分,那么这个节点就会从当前位置移动到childNodes列表的最后一位

insertBefore()

如果想把节点插到特定的位置,此时就需要使用insertBefore()方法,这个方法接受两个参数:要插入的节点作为参照的节点insertBefore()会将节点插入到参照节点的前面。同时返回新插入的节点

// 当参照节点是null的时候,插入成为最后一个节点。
let returnedNode = someNode.insertBefore(newNode, null);
console.log(someNode.lastChild === returnedNode); // true

// 插入成为第一个节点
let returnedNode = someNode.insertBefor(newNode, someNode.firstChild);
console.log(someNode.firstChild === returnedNode); // true

replaceChild()和removeChild()

  • replaceChild()
    replaceChild()方法用来替换节点,它接受两个参数:要插入的节点要替换的节点。并返回要替换的节点,而这个要替换的节点会被从DOM树上删除
// 替换第一个节点
let returnedNode = someNode.replaceChild(newNode, someNode.firstChild);

// 替换最后一个节点
let returnedNode = someNode.replaceChild(newNode, someNode.lastChild);
  • removeChild()
    如果你只想移除某个节点,而并不像替换它,则可以使用removeChild()方法。这个方法接受一个值,就是要移除的节点,这个要移除的节点会被作为该方法的返回值进行返回
// 移除第一个节点
let returnedNode = someNode.removeChild(someNode.firstChild);
// 移除最后一个节点
let returnedNde = someNode,removeChild(someNode.lastChild)

cloneNode()

这个方法是所有的节点都有的,用于创建调用这个方法的节点的一个副本。cloneNode()方法接受一个布尔值参数,在参数是true的时候,表示执行深复制,也就是复制节点本身和整个子节点树。值为false,表示执行浅复制,即只复制这个节点本身。复制后返回的节点副本属于文档所有,但是并没有给它指定父元素,因此这个副本就变成了一个“孤儿”。除非将它通过appendChild()insertBefore()replaceChild()将它插入到文档树中。
假如有以下的HTML结构:

<ul>
  <li>item1</li>
  <li>item2</li>
  <ii>item3<li>
</ul>

假设我们以及把ul元素的引用储存在了myList变量中,那么通过下面代码就可以看到cloneChild()两种模式的区别。

let deepList = myList.cloneChild(true);
console.log(deepList.childNodes.lengh); //3 (IE < 9) 或 7(其他浏览器)

let shallowList = myList.cloneChild(false);
console.log(shallowList.childNodes.length); // 0

查找元素

说到常见的DOM应用,恐怕就要数取得特定的几个或某个元素的引用,从而进行操作了。取得元素的方法可以使用定义在document对象中的一些方法。

getElementById()

getElementById()接受一个参数,这个参数是要取得的元素的id值**。这里的id值必须与元素的id属性值一模一样**。以下面的元素为例:

<div id="myDiv">item1</div>

// 可以使用下面的方法获取到这个div元素
let element = document.getElementById('myDiv');

如果页面中有多个id值一样的元素,getElementById()只会返回第一次出现的元素

getElementsByTagName()

这个方法接受一个参数,即要获取的元素的标签名,而返回的是零个或多个元素的NodeList。

// 获取页面中的所有的img元素,并将返回的集合保存咋images变量中
let images = document.getElementsByTagName('img');

// 此时的images变量和NodeList很类似,可以使用[]或item()来访问其中的项
console.log(images.length); //img元素的数量
console.log(images[0].src); // 第一个img元素的src属性值

getElementsByName()

这个方法会返回带有给定name属性的所有元素。最常使用该方法来获取单选按钮,不过要求所有的单元按钮具备相同的name属性值

<div>
  <ul>
     <li> <input type="radio" name="color" value="red" id="colorRed"/></li>
     <li> <input type="radio" name="color" value="green" id="colorGreen"/></li>
     <li> <input type="radio" name="color" value="blue" id="colorBlue"/></li>
   <ul>
</div>

// 获取name值为color的单选按钮元素
var radio = document.getElementsByName("color");

querySelector()

querySelector()接受一个css选择符,返回与该模式匹配的第一个元素,如果没有,就返回null

// 获取body 元素
var body = document.querySelector("body");

// 获取id为#myDiv的元素
var div = dosument.querySelector("#myDiv")

// 获取类为selector的元素
var element = document.querySelector(".selector")

// 获取类为button的第一个ing元素
var img = document.querySelector("img.button")

querySelectorAll()

querySelectorAll()方法接受的参数与querySelector()一样,但返回的是所有匹配的元素,而不是第一个元素。

// 获取类为selector的元素
var elements = document.querySelectorAll(".selector")
// 获取p元素中的所有strong元素
var strongs = document.querySelectorAll("p strong");
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值