前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具

DOM

作者头像
奋飛
发布2021-08-30 11:22:24
发布2021-08-30 11:22:24
1.5K00
代码可运行
举报
文章被收录于专栏:Super 前端Super 前端
运行总次数:0
代码可运行

下述内容主要讲述了《JavaScript高级程序设计(第3版)》第10章关于“DOM”。

DOM(文档对象模型)是针对HTML和XML文档的一个API(应用程序编程接口)。DOM描绘了一个层次变化的节点树,允许开发人员添加、移除和修改页面的某一部分。

一、节点层次

在HTML页面中,文档元素始终都是元素。

1. Node类型

JavaScript中的所有节点类型都继承自Node类型,因此所有节点类型都共享着相同的基本属性和方法。 (1)nodeType属性:用于表明节点的类型。

常量

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

需要注意的是,在IE中不支持常量

代码语言:javascript
代码运行次数:0
运行
复制
if(someNode.nodeType === 1){	// 不使用Node.ELEMENT_NODE
	console.log("node is an element");
}

(2)nodeName和nodeValue

代码语言:javascript
代码运行次数:0
运行
复制
if(someNode.nodeType === 1){
    var name = someNode.nodeName, 	// 元素的标签名
        value = someNode.nodeValue; // null
    console.log(name, value);
}

(3)节点关系 文档中所有节点之间都存在着这样或那样的关系。节点间的各种关系可以用传统的家族关系来描述,相对于把文档树比喻成家谱

属性

说明

childNodes

直接子元素;nodeList对象,保存一组有序节点,可通过位置访问

parentNode

文档树中的父节点

previousSibling

前一个兄弟节点

nextSibling

后一个兄弟节点

firstChild

第一个子节点

lastChild

最后一个子节点

ownerDocument

整个文档的文档节点Document

说明:

  • hasChildNodes()在节点包含一个或多个子节点的情况下返回true
  • NodeList对象拥有length属性,但并不是Array实例;其是基于DOM结构动态执行查询的结果,因此DOM结构的变化能够自动反应在NodeList对象中。可以通过方括号,也可以使用item()方法访问NodeList中的节点。

示例

代码语言:javascript
代码运行次数:0
运行
复制
    李刚
    ligang
    http://blog.csdn.net/ligang2585116
代码语言:javascript
代码运行次数:0
运行
复制
var div = document.getElementById("content");
console.log(div.hasChildNodes());   // true
console.log(div.ownerDocument);     // #document

var children = div.childNodes;
console.log(children[0]);       // 李刚  注意:这里有可能是#text,格式化回车缩进导致!!
console.log(children.item(1));  // ligang

var p1 = div.firstChild;
console.log(p1.parentNode);         // ​…​​
console.log(p1.previousSibling);    // null
console.log(p1.nextSibling);        // ligang

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

方法

说明

appendChild(newDom)

向childNode列表的末尾添加一个节点

inserBefore(newDom, 参照节点)

新插入的节点作为参照节点的同胞节点,同时返回该插入节点

replaceChild(newDom, 被替换的节点)

新插入的节点将占据被替换节点的位置

removeChild(要移除的节点)

返回被移除的节点,被移除的节点仍然为稳当所有,只是在文档中没有了位置

注意:并不是所有节点都有子节点,如果在不支持子节点的节点上调用了上述方法,将会导致错误发生。 示例:将blog元素移动到content中

代码语言:javascript
代码运行次数:0
运行
复制
    李刚

http://blog.csdn.net/ligang2585116
代码语言:javascript
代码运行次数:0
运行
复制
var div = document.getElementById("content"),
    p = document.getElementById("blog");
div.appendChild(p);
代码语言:javascript
代码运行次数:0
运行
复制
    李刚
    http://blog.csdn.net/ligang2585116

说明:如果传入到appendChild()中的节点已经是文档的一部分了,那结果就是将该节点从原来的位置转移到新位置。

示例:将blog作为content的第一个子元素,将company作为content的最后一个子元素

代码语言:javascript
代码运行次数:0
运行
复制
    李刚

http://blog.csdn.net/ligang2585116
ptmind
代码语言:javascript
代码运行次数:0
运行
复制
var content = document.getElementById("content"),
    blog = document.getElementById("blog"),
    company = document.getElementById("company");
content.insertBefore(blog, content.childNodes.item(0)); // content.firstChild
content.insertBefore(company, null);
代码语言:javascript
代码运行次数:0
运行
复制
    李刚
    http://blog.csdn.net/ligang2585116
	ptmind

(5)其他方法

方法

说明

cloneNode(boolean)

true:复制节点及整个子节点树;false:只复制节点本身

normalize()

处理文档树中的文本节点

所有节点都有上述方法!

2. Document类型

JavaScript通过Document类型表示文档。在浏览器中,document对象是HTMLDocument的一个实例,表示整个HTML页面。而且,document对象是window对象的一个属性。

代码语言:javascript
代码运行次数:0
运行
复制
document.documentElement; // 获取对的引用
document.body;	// 获取对的引用
/* 以本人blog为例 */
document.title;	// 获取页面title信息:"李刚的学习专栏 - 博客频道 - CSDN.NET"
document.URL;	// 获取页面完整的URL:"http://blog.csdn.net/ligang2585116"
document.domain;	// 获取页面的域名:"blog.csdn.net"	
document.referrer;	// 获取链接到当前页面的那个页面的URL:直接访问为空!

技巧:由于跨域安全限制,来自不同子域的页面无法通过JavaScript通信。而通过将每个页面的document.domain设置为相同的值,这些页面就可以互相访问对方包含的JavaScript对象了。例如,在www.xxx.com中嵌入了一框架,框架内页面加载自report.xxx.com;两者不能进行访问。可以将两个页面的document.domain值都设置为xxx.com,就可以互相访问了。 需要注意的是,浏览器对domain有一限制,即如果域名开始时松散的(xxx.com),那么不能将它再设置为紧绷的(www.xxx.com)。 (1)查找元素

方法

说明

getElementById()

只返回文档中第一次出现的元素;如果不存在带有相应id的元素,则返回null

getElementsByTagName()

返回的是包含零或多个元素的HTMLCollection对象

getElementsByName()

返回带有指定name特性的所有元素

代码语言:javascript
代码运行次数:0
运行
复制
var images = document.getElementsByTagName("img");
images.item(0);
images.namedItem("myImage");

上述两种方式都可以通过[]代替。在后台,对数值索引会调用item(),对字符串索引会调用namedItem()。 (2)特殊集合

属性

说明

document.anchors

包含文档中所有带name特性的元素

document.applets

包含文档中所有的元素

document.forms

包含文档中所有的元素

document.images

包含文档中所有的元素

document.links

包含文字所有带href特性的元素

(3)DOM一致性检测

代码语言:javascript
代码运行次数:0
运行
复制
document.implementation.hasFeature("名称", "版本号");
document.implementation.hasFeature("XML", "1.0");	// true

存在实现与规范不一致的情况,所以建议除了检测hasFeature()之外,还同时使用能力检测。 (4)文档写入

方法

说明

write()

原样写入

writeln()

在字符串末尾添加有一个换行符(\n)

open()

打开网页输出流

close()

关闭网页输出流

示例:

代码语言:javascript
代码运行次数:0
运行
复制
my name is:
document.write("ligang");	// my name is: ligang
window.onload = function(){
    document.write("ligang"); // ligang
};

在文档加载结束后再调用document.write(),输出的内容将会重写整个页面。 write()、writeln()可以动态包含外部资源,需注意不能直接包含"",因为其会被解释为脚本块的结束。

代码语言:javascript
代码运行次数:0
运行
复制
document.write("<\/script>"); // ligang
</code></pre> 
<h4><a id="3_Element_221"></a>3. Element类型</h4> 
<p>Element类型用于表现XML和HTML元素。可以通过nodeName或tagName属性获取元素的标签名。<br> <strong>注意</strong>:在HTML中,标签名都以大写字母表示;在XML中,标签名始终与源代码中的保持一致。<br> (1)HTML元素的标准特性<br> 示例:<br> <code><div id="myDiv" title="ligang Demo" lang="zh" dir="ltr" class="bd bf">http://blog.csdn.net/ligang2585116</div></code></p> 
<table><thead><tr><th align="left">属性</th><th align="left">说明</th><th align="left">值</th></tr></thead><tbody><tr><td align="left">div.id</td><td align="left">元素在文档中的唯一标识符</td><td align="left">“myDiv”</td></tr><tr><td align="left">div.title</td><td align="left">附件说明信息,悬停展示</td><td align="left">“ligang Demo”</td></tr><tr><td align="left">div.lang</td><td align="left">元素内容的语言代码</td><td align="left">“zh”</td></tr><tr><td align="left">div.dir</td><td align="left">语言方向:ltr左到右;rtly右到左</td><td align="left">“ltr”</td></tr><tr><td align="left">div.className</td><td align="left">CSS类</td><td align="left">“bd bf”</td></tr></tbody></table>
<p>(2)特性<br> 获取特性:<code>dom.getAttribute("特性名")</code> 如不存在返回null</p> 
<p>注意有两类特殊的特性:</p> 
<ul><li>style,返回CSS文本,通过属性访问则返回一个对象;</li><li>onclick等事件处理程序,返回相应代码的字符串。</li></ul> 
<p><strong>示例</strong>:</p> 
<pre><code><a href="javscript:;" style="background-color: grey;text-underline: none;"
   onclick="function(){console.log('la')}">http://blog.csdn.net/ligang2585116</a>
</code></pre> 
<pre><code>var a = document.getElementsByTagName("a")[0];
a.getAttribute("style");	// "background-color: grey;text-underline: none;"
a.style;	// CSSStyleDeclaration {0: "background-color", all: ""…}
a.getAttribute("onclick");	// "function(){console.log('la')}"
</code></pre> 
<p>设置特性:<code>dom.setAttribute("特性名","值")</code><br> (3)attributes属性<br> attributes属性中包含一个<code>NamedNodeMap</code></p> 
<table><thead><tr><th align="left">属性</th><th align="left">说明</th></tr></thead><tbody><tr><td align="left">dom.attributes.getNamedItem(name)</td><td align="left">返回nodeName属性等于name的节点</td></tr><tr><td align="left">dom.attributes.removeNamedItem(name)</td><td align="left">从列表中移除nodeName属性等于name的节点</td></tr><tr><td align="left">dom.attributes.setNamedItem(attr)</td><td align="left">向列表中添加节点,以节点的nodeName属性为索引</td></tr><tr><td align="left">dom.attributes.item(pos)</td><td align="left">返回位于数字pos位置处的节点</td></tr></tbody></table>
<p><strong>示例</strong>:设置属性</p> 
<pre><code>// 方式一:示例:setNamedItem
var target = document.createAttribute("target");
target.nodeValue = "_blank";
a.attributes.setNamedItem(target);
// 方式二:setAttribute
a.setAttribute("target", "_blank");
</code></pre> 
<p>(4)创建元素</p> 
<pre><code>document.createElement("元素名/完整元素");
</code></pre> 
<p>创建新元素的同时,也为新元素设置了ownerDocument属性。<br> <strong>示例</strong>:创建元素并添加到文档树</p> 
<pre><code>var a = document.createElement("a");
a.href = "http://blog.csdn.net/ligang2585116";
a.text = "http://blog.csdn.net/ligang2585116";
document.body.appendChild(a);
</code></pre> 
<p>(5)元素的子节点<br> 元素可以有任意数量的子节点和后代节点。<br> <strong>示例</strong>:为了兼容浏览器差异</p> 
<pre><code>for(var i = 0, len = element.childNodes.length; i < len; i++){
	if(element.childNodes[i].nodeType === 1){
		// 执行某些操作
	}
}
</code></pre> 
<h4><a id="4_Text_306"></a>4. Text类型</h4> 
<p>文本节点由Text类型表示,包含纯文本。纯文本可以包含转义后的HTML字符,但不能包含HTML代码。<br> (1)创建文本节点:<code>document.createTextNode("文本")</code><br> (2)规范化文本节点:在一个包含两个或多个文本节点元素上调用<code>normalize()</code>,则将会所有文本节点合并成一个节点。<br> (3)分割文本节点:将一个文本节点分成两个文本节点,按指定的位置分割nodeValue值。<br> <strong>示例</strong>:规范化文本节点</p> 
<pre><code>var div = document.getElementById("content");
var textNode = document.createTextNode("Hello"),
    anotherNode = document.createTextNode("Ligang");
div.appendChild(textNode);
div.appendChild(anotherNode);
console.log(div.childNodes.length);	// 2
div.normalize();
console.log(div.childNodes.length);	// 1
var newNode = div.firstChild.splitText(5);	// "Ligang"
console.log(div.childNodes.length);	// 2
</code></pre> 
<h4><a id="5_Comment_326"></a>5. Comment类型</h4> 
<p>注释在DOM中是通过Comment类型来表示的。<br> Comment类型与Text类型继承自相同的基类,因此它拥有除了splitText()之外的所有方法,当然也可通过nodeValue或data属性来取得注释的内容。</p> 
<h4><a id="6_DocumentFragement_329"></a>6. DocumentFragement类型</h4> 
<p>DocumentFragement类型中没有对应的标记,DOM规定文档片段是一种“轻量级”的文档,可以包含和控制节点,但不会像完整的文档那样占用额外的资源。可以当做“仓库”使用。<br> <strong>示例</strong>:</p> 
<pre><code>var fragment = document.createDocumentFragment();
var li = null;
for(var i = 0; i < 5; i++){
    li = document.createElement("li");
    li.appendChild(document.createTextNode("Item "+ (i+1)));
    fragment.appendChild(li);
}
// 文档片段的所有子节点都被删除并转移到<ul>元素中
document.getElementById("myUl").appendChild(fragment);
</code></pre> 
<h4><a id="7__345"></a>7. 其他类型</h4> 
<p>CDATASection类型、DocumentType类型很少用到,这里不再赘述。</p> 
<h3><a id="DOM_347"></a>二、DOM操作技术</h3> 
<h4><a id="1__348"></a>1. 动态脚本</h4> 
<p>在元素添加到页面之前,是不会下载外部文件的。(不同于image)<br> 相关内容请查看:<a href="http://blog.csdn.net/ligang2585116/article/details/52028989">事件:事件类型-UI事件</a></p> 
<p><strong>示例</strong>:动态加载JavaScript文件</p> 
<pre><code>function loadScript(url){
    var script = document.createElement("script");
    script.type = "text/javascript";
    script.src = url;
    document.body.appendChild(script);
}
</code></pre> 
<p><strong>示例</strong>:动态加载JavaScript代码</p> 
<pre><code>function loadScriptString(code){
    var script = document.createElement("script");
    script.type = "text/javascript";
    try{
        script.appendChild(document.createTextNode(code));
    }catch (e){
        script.text = code; // 兼容IE
    }
    document.body.appendChild(script);
}
</code></pre> 
<h4><a id="2__378"></a>2. 动态样式</h4> 
<p>同动态加载脚本类似,添加到页面之后才会加载资源。</p> 
<p><strong>示例</strong>:动态加载CSSt文件</p> 
<pre><code>function loadStyle(url){
    var link = document.createElement("link");
    link.rel = "stylesheet";
    link.type = "text/css";
    link.href = url;
    document.head.appendChild(link);
}
</code></pre> 
<p><strong>示例</strong>:动态加载CSS代码</p> 
<pre><code>function loadStyleString(code){
    var style = document.createElement("style");
    style.type = "text/css";
    try{
        style.appendChild(document.createTextNode(code));
    }catch (e){
        style.stylesheet.cssText = code;	// 兼容IE
    }
    document.head.appendChild(style);
}
</code></pre> 
<h4><a id="3__408"></a>3. 操作表格</h4> 
<p>为了方便构建表格,HTML DOM还为<code><table></code>、<code><tbody></code> 和 <code><tr></code>元素添加了一些属性:<br> 为<code><teble></code>元素添加的属性和方法:</p> 
<table><thead><tr><th align="left">属性方法</th><th align="left">说明</th></tr></thead><tbody><tr><td align="left">caption</td><td align="left">(若有)保存着对<code><caption></code>元素的指针</td></tr><tr><td align="left">tHead</td><td align="left">(若有)保存着对<code><tHead></code>元素的指针</td></tr><tr><td align="left">tFoot</td><td align="left">(若有)保存着对<code><tFoot></code>元素的指针</td></tr><tr><td align="left">tBodies</td><td align="left">一个所有<code><tbody></code>元素的HTMLCollection</td></tr><tr><td align="left">rows</td><td align="left">一个所有行的HTMLCollection</td></tr><tr><td align="left">createCaption</td><td align="left">创建<code><caption></code>元素,放到表格中,返回引用</td></tr><tr><td align="left">createTHead()</td><td align="left">创建<code><thead></code>元素,放到表格中,返回引用</td></tr><tr><td align="left">createTFoot()</td><td align="left">创建<code><tfoot></code>元素,放到表格中,返回引用</td></tr><tr><td align="left">deleteCaption()</td><td align="left">删除<code><caption></code>元素</td></tr><tr><td align="left">deleteTHead()</td><td align="left">删除<code><thead></code>元素</td></tr><tr><td align="left">deleteTFoot()</td><td align="left">删除<code><tfoot></code>元素</td></tr><tr><td align="left">insertRow(pos)</td><td align="left">向rows集合中的指定位置 插入一行</td></tr><tr><td align="left">deleteRow(pos)</td><td align="left">删除指定位置的一行</td></tr></tbody></table>
<p><code><tbody></code>元素添加的属性和方法:</p> 
<table><thead><tr><th align="left">属性方法</th><th align="left">说明</th></tr></thead><tbody><tr><td align="left">rows</td><td align="left">一个保存着<code><tbody></code>元素中行的HTMLCollection</td></tr><tr><td align="left">insertRow(pos)</td><td align="left">向rows集合中指定位置插入一行,返回新行的引用</td></tr><tr><td align="left">deleteRow(pos)</td><td align="left">删除指定位置的行</td></tr></tbody></table>
<p><code><tr></code>元素添加的属性和方法:</p> 
<table><thead><tr><th align="left">属性方法</th><th align="left">说明</th></tr></thead><tbody><tr><td align="left">cells()</td><td align="left">一个保存着<code><tr></code>元素中的单元格的HTMLCollection</td></tr><tr><td align="left">insertCell(pos)</td><td align="left">向cells集合中的指定位置插入一个单元格,返回新单元格引用</td></tr><tr><td align="left">deleteCell(pos)</td><td align="left">删除指定位置的单元格</td></tr></tbody></table>
<p><strong>总结</strong>:NodeList、NameNodeMap和HTMLColletction三个集合都是动态的。应尽量减少访问NodeList的次数,因为每次访问NodeList都会运行一次基于上下文档的查询。可以考虑将从NodeList中取得的值缓存起来!</p>
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016/11/01 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、节点层次
    • 1. Node类型
    • 2. Document类型
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档