《JavaScript高级程序设计》- 第十四章:DOM

本文详细介绍了DOM(文档对象模型)的相关知识,包括节点层级、DOM编程、MutationObserver接口等。重点讲解了Node类型、Document类型、Element类型、Text类型、Comment类型以及MutationObserver的基本用法和性能优化。此外,还探讨了动态脚本、动态样式、操作表格的便捷方法,以及如何高效使用NodeList。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第十四章:DOM

文档对象模型(Document Object Model)是HTML 和 XML文档的编程接口;就是开发者可以通过JavaScript编程,添加、删除、修改页面的各个部分;

14.1 节点层级

任何HTML\XML文档都可以表示为由节点构成的层级结构。

<html>
    <head>
        <title>Sample Page</title>
    </head>
    <body>
        <p>Hello World!</p>
    </body>
</html>

在HTML中,文档元素(document)每个文档只能拥有一个,而且是最外层元素,其有且只有一个直接子元素<html>

14.1.1 Node类型

DOM Level 1描述了Node的接口,这个接口是所有DOM节点类型都必须实现的

Node接口在JavaScript中被实现为Node类型。

在JavaScript中,所有节点类型都继承Node类型,一共有12种类型并用12个常量表示

(也可以使用其中的数字代替):

  • Node.ELEMENT_NODE(1)

  • Node.ATTRIBUTE_NODE(2)

  • Node.TEXT_NODE(3)

  • Node.CDATA_SECTION_NODE(4)

  • Node.ENTITY_REFERENCE_NODE(5)

  • Node.ENTITY_NODE(6)

  • Node.PROCESSING_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)

节点信息

  • nodeName:存储着节点的名字,如div、img
  • nodeValue:存储着节点的值,若为标签,则值为null
  • nodeType:存储着节点类型,对应着上面的12种类型

节点关系

文档中各节点都具有关系,相当于一个族谱,主要为父元素和子元素两种区别;

  1. childNodes:每个节点都拥有该属性,该属性包含一个NodeList实例,是一个类数组对象有序存储着该节点的所有直接子节点NodeList实例是实时的活动对象,这就意味着,DOM树改变NodeList也会改变,反之亦然;
    • 由于是一个类数组对象,所以可以通过[]访问其中元素;
    • 也可以通过length属性,获取子元素个数。
  2. parentNode:指向父节点
  3. previousSibling:指向前一个兄弟节点,childNodes[0].previousSiblingnull
  4. nextSibling:指向后一个兄弟节点,childNodes[childNodes.length-1].nextSiblingnull
  5. firstChild/lastChild:指向第一个子节点、最后一个子节点
  6. hasChildNodes():返回true,表示有一个或多个节点;
  7. ownerDocument:指向文档中唯一的文档节点(document)。

操纵节点

添加节点:

  1. appendChild():向尾部追加一个节点;接收一个参数:

    • 需要添加的节点
  2. insertBefore():在参照节点前插入一个节点;接收两个参数:

    • 需要添加的节点;
    • 参照节点;

    如果参照节点为null,则效果与appendChild()一样;

  3. replaceChild():替换目标节点;接收两个参数:

    • 要插入的节点
    • 要替换的节点

    被替换的节点,会完全消失在DOM树中。

删除节点:

  1. removeChild():删除一个节点;接收一个参数:

    • 要删除的节点

    会返回被删除的节点

克隆节点:

  1. cloneNode():克隆一个节点,接收一个参数:

    • 布尔值,表示是否深克隆;如果为true,则克隆该节点以及其子节点。

    返回被克隆的节点;如果被克隆的节点没有指定父节点,则称为孤儿节点

    注意,该克隆方法,不会克隆节点的JavaScript属性,如时间处理程序,只复制HTML属性

14.1.2 Document类型

JavaScript中表示文档节点类型。在浏览器中,documentHTMLDocument的实例,表示整个页面

document对象是只读的,一般不会存在诸如appendChild()等方法

Document类型有如下特征:

  • nodeType等于9;
  • nodeName值为"#document";
  • nodeValue值为null;
  • parentNode值为null;
  • ownerDocument值为null;
  • 子节点可以是DocumentType(最多一个) 、 Element(最多一个) 、 ProcessingInstruction或Comment类型。

文档子节点:

document提供了三个访问子节点的快捷方式:

  1. document.documentElement:始终指向<html>元素
  2. document.body:始终指向<body>元素
  3. document.doctype:始终指向<!DOCTYPE>元素

文档信息

document提供了浏览器加载网页的信息

  1. document.title:获取<title>标签的内容,可修改,并会渲染到网页中。
  2. document.URL:获取当前页面的URL
  3. document.domain:获取当前页面的域名
  4. document.referrer:获取当前页面来源

注意:

  • URL和domain是相关的,若URL为https://www.baidu.com/search=xxxx,则域名为www.baidu.com;

  • 后面三个属性中,只有domain是可设置的。处于安全考虑,domain只能设置为URL中的子集

    // 当前URL为:www.p2p.baidu.com
    document.domain = 'p2p.baidu';	// 成功
    document.domain = 'baidu.com';	// 成功
    document.domain = 'hahaha.net';	// 失败
    
  • 当页面包含来自不同子域的窗格(<frame>)或内嵌窗格(<iframe>)时,设置domain是有用的。因为跨源通信存在安全隐患;所以可以把每个页面上的domain都设置为相同的值,就可以访问对方的JavaScript对象

  • domain属性,一旦收紧了,就不能再放松了

    // 当前URL为:www.p2p.baidu.com
    document.domain = 'p2p.baidu.com';	// 放松了,成功
    document.domain = 'baidu.com';		// 继续放松了,成功
    document.domain = 'p2p.baidu.com';	// 再次收紧了,错误!
    

定位元素

document提供了定位元素的方法

  • getElementById():根据id属性获取节点。因为id是唯一的,所以返回第一个找到的。
  • getElementsByClassName():根据class属性获取节点。
  • getElementsByTagName():根据标签名获取节点。
  • getElementsByName():根据name属性获取节点。

除了第一个方法,其余的都是返回一个HTMLCollection对象;该对象也是类数组对象

特殊集合

  • document.anchors包含文档中所有带name属性的<a>元素;
  • document.forms包含文档中所有<form>元素;
  • document.images包含文档中所有<img>元素;
  • document.links包含文档中所有带href属性的<a>元素。

文档写入

  • write():向文档输入信息,接收一个参数:输入内容
  • writeln():上前者一致,只不过会自动添加换行符

注意:

  • 这两个方法需要只能在页面渲染器使用,如果渲染完毕在调用,内容会覆盖整个页面

  • 当使用这个方法动态写入外部资源时,需要注意:

    <html>
    <head>
        <title>document.write() Example</title>
    </head>
    <body>
        <script type="text/javascript">
            document.write("<script type=\"text/javascript\" src=\"file.js\">" +
                "<\/script>");</script>
    </body>
    </html>
    

    在输出内容的第二个script前面,必需加上转义字符,不然会匹配错误;

14.1.3 Element类型

除Document类型外,Element类型就是Web开发中最常用的类型;Elment表示HTML元素,对外暴露访问元素标签名、子节点和属性的能力

Element类型具有以下特征:

  • nodeType等于1;
  • nodeName值为元素的标签名;
  • nodeValue值为null;
  • parentNode值为Document或Element对象;子节点可以是Element、 Text、 Comment、ProcessingInstruction、 CDATASection类型。

特征提取

  • nodeNametagName属性都可以获取Elment元素的标签名,且在HTML中,元素标签名始终以全大写表示

为了防止提取标签名的时候,大小写混乱,推荐如下操作:

if(element.tagName.toLowerCase() == 'div'){
   
    // do something
}

HTML元素

所有HTML元素,都是通过HTMLElement类型标识,包括直接实例和间接实例;

HTMLElement直接继承自Element,并增加了一些标准属性

  • id, 元素在文档中的唯一标识符;
  • title, 包含元素的额外信息, 通常以提示条形式展示;
  • lang, 元素内容的语言代码(很少用) ;
  • dir, 语言的书写方向("ltr"表示从左到右, "rtl"表示从右到左, 同样很少用) ;
  • className, 相当于class属性, 用于指定元素的CSS类(因为class是ECMAScript关键字, 所以不能直接用这个名字)。

可以直接获取、修改这些值:

// <div id='myDiv' class='myClass' title='hello world'>
let div = document.getElementById('myDiv');
console.log(div.class);	// myClass
div.class = 'myLess';
console.log(div.class);	// myLess

修改这些属性会对页面产生影响。

操作属性

每个元素有零个或多个属性,我们可以通过如下三个方法来操作属性:

  • getAttribute():获取属性,接收一个参数:属性名
  • setAttribute():设置属性,接收两个参数:属性名,属性值
  • removeAttribute():移除属性,接收一个参数:属性名

注意:以上说所三种操作属性的方法:

  • 既可以操作标准属性(又称:公认属性)、也可以操作自定义属性;
  • 属性名不区分大小写
  • 在HTML5的规范中,,自定义属性需要加data-为前缀,方便验证;
  • 自定义属性不会称为DOM对象属性,即不会称为公认属性或标准属性;
  • 不仅仅可以获取一般属性,还可以获取事件属性:如onclick;
  • 如果使用getAttribute()来获取事件属性值,则以字符串的形式返回源代码;通常直接访问事件属性:element.onclick,则返回一个函数;
  • 开发者一般使用getAttribute()来访问自定义属性,而公认属性可以直接访问:element.id

attributes属性

attributes属性与childNodes属性类似,也是类似NodeList的实时集合,每个属性表示为Attr节点,保存在NamedNodeMap对象中,其包含如下方法:

  • getNamedItem(name), 返回nodeName属性等于name的节点;
  • removeNamedItem(name), 删除nodeName属性等于name的节点;
  • setNamedItem(node), 向列表中添加node节点, 以其no
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值