资讯专栏INFORMATION COLUMN

JavaScript高级-unit10 DOM

kohoh_ / 2245人阅读

摘要:在浏览器中,对象是继承自类型的一个实例,表示整个页面。一致性检测属性提供相应信息和功能的对象,与浏览器对的实现直接对应。在中,标签名始终都以全部大写表示而在有时包括,标签名始终与源代码中的保持一致。设置的特性名统一转为小写。

简介

DOM描述了一个层次化的节点树,允许开发人员添加、移除和修改页面。

节点

根据 W3C 的 HTML DOM 标准,HTML 文档中的所有内容都是节点:

整个文档是一个文档节点

每个 HTML 元素是元素节点

HTML 元素内的文本是文本节点

每个 HTML 属性是属性节点

注释是注释节点

每个节点都有一个nodeType属性,用于表明节点的类型。并不是所有节点类型都受到Web浏览器支持,最常用的事元素和文本节点。

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没有公开Node类型的构造函数,所以确定节点类型如下:

// nodeType 是只读的
if (someNode.nodeType == 1) {
    alert("Node is an element");
}
Node类型

1、nodeName 和 nodeValue 属性

// 使用前先检查节点类型,确认是否是一个元素,对于元素节点
// nodeName 保存的是标签名(节点的名称),nodeValue = null (节点的值);
if (someNode.nodeType == 1) {
    value = someNode.nodeName;    // nodeName的值是元素的标签名
}

2、 节点关系

每个节点都有一个 childNodes 属性,保存着一个 NodeList 对象。

是一个数组对象,保存一组有序的节点,可以通过位置访问节点。有length属性,但不是数组实例。

基于DOM结构动态执行查询结果,结构的变化能够自动反应着NodeList对象中。

可以用 item() 方法访问其中的节点。

var firstChild  = someNode.childNodes[0];
var secondChild = someNode.childNodes.item(1); 

// 将NodeList对象转化为数组
function convertToArray(nodes) {
    var array = null;
    try {
        array = Array.prototype.slice.call(node,0);    // 针对非 IE 浏览器
    } catch {
        array = new Array();
        for (var i=0, len=nodes.length; I < len; i++) {
            array.push(nodes[I]);
        }
    }
    return array;
}

parentNode 属性:指向文档树中的父节点

父节点的 firstChild 和 lastChild 属性指向第一个和最后一个

previousSibling: 上一个同胞节点

nextSibling: 下一个同胞节点

hasChildNodes(): 节点包含一个或多个子节点返回 true

ownerDocument: 指向表示整个文档的文档节点

document.documentElement - 全部文档

document.body - 文档的主体

3、操作节点

以下方法都需要取得父节点(使用 parentNode 属性)

appendChild(): 向 childNodes 列表末尾添加一个节点。如果已存在,从原来位置移动到新位置

insertBefore(): 插入节点,接受两个参数,要出入的节点和参考节点(谁的前面)

replaceChild(): 替换节点,接受两个参数,要插入的节点和要替换的节点

removeChild(): 移除节点

以下两个方法是所有类型的节点都有

cloneNode(): 创建节点的副本,参数为true,复制节点及整个子节点树,false只复制节点本身,没有父节点,需要用上面方法添加到文档中

normalize(): 处理文档树中的文本节点。可能会出现文本节点不包含文本,或者接连出现两个文本节点。调用这方法,如果找到空文本,则删除;找到相邻文本节点,则合并为一个

Document 类型

JavaScript通过 Document 类型表示文档。在浏览器中,document 对象是 HTMLDocument(继承自 Document 类型)的一个实例,表示整个HTML页面。而且 document 也是 window 对象的一个属性,因此可以将其作为全局对象来访问。通过这个文档对象,不仅可以取得与页面有关的信息,而且还能操作页面的外观及其底层结构。

nodeName 的值为 “#document”;

nodeValue 的值为 null;

parentNode 的值为 null;

ownerDocument 的值为 null;

其子节点可能是一个 DocumentType(最多一个)、Element(最多一个)、ProcessingInstruction 或 Comment。

1、文档的子节点

内置的访问子节点的快捷方式:

documentElement 属性:始终指向HTML页面的元素

childNodes 列表访问文档元素

作为内置的HTMLDocument对象,document 对象有一个 body 属性,直接指向 元素。

// 所有浏览器都支持
var html = document.documentElement;    // 取得对对引用
var body = document.body;    // 取得对对引用

用不着在 document 对象上调用 appendChild()、removeChild()和replaceChild()方法,因为文档类型(如果存在)是只读的,而且它只能有一个元素子节点(通常早存在)。

2、文档信息

document 对象还有一些标准的Document对象所没有的属性。这些对象表现的网页的一些信息。

// 取的文档标题
var originalTitle = document.title;
// 设置文档标题
document.title = "New page title";

// 取得完成的URL
var url = document.URL;
// 取的域名
var domain = document.domain;
// 取的来源页面的URL
var referrer = document.referrer; 

只有 domain 可以设置,如果包含子域名,不能设置为URL中不包含的域。

由于跨域安全限制,来自不同子域的页面无法通过 Javascript 通信,可以将每个页面的document.domain设置为相同值,就可以互相访问对方包含的JavaScript对象了。

如果域名一开始是“松散的”,就不能设为“紧绷的”,设为“wrox.com”,就不能设为“p2p.wrox.com”。

3、查找元素

取得特定的某个或某组元素的引用,然后执行一些操作。

getElementById(): 要获取的元素 id,返回第一个出现的,如果没找到返回 null

getElementsByTagName(): 参数(要取得元素的标签名),返回包含零个或多个元素的 NodeList。在HTML文档中,返回一个 HTMLCollection 对象,作为动态集合。传入“*”,取得文档中的所有元素

getElementsByName(): 返回给定 name 特性的所有元素。最常用取得单选按钮(单选按钮必须具有相同的 name 特性)

// 取得页面中所有的元素,并返回一个HTMLCollection
var images = document.getElementsByTagName("img");
alert(images.length);    // 图像的数量
alert(images[0].src);    // 第一个图像元素的src特性
alert(images.item(0).src);    // 第一个图像元素的src特性

HMTLCollection 对象

有一个 namedItem() 方法,可以通过元素的 name 特性取得集合中的项

支持按名称访问项


var myImage = images.namedItem("myImage");

var myImage = images["myImage"];

4、特殊集合

除了属性和方法,document 对象还有一些特殊的集合,都是 HTMLCollection对象,

document.anchors ,包含文档中所有带 name 特性的 元素;

document.applets ,所有的 元素,不建议使用;

document.forms ,文档中所有的

元素;

document.images ,文档中所有的 元素;

document.links ,文档中所有带 href 特性的 元素。

5、DOM一致性检测

document.implementation 属性提供相应信息和功能的对象,与浏览器对 DOM 的实现直接对应。
规定一个方法:hasFeature(),接受两个参数:要检测的 DOM 功能名称及版本号

var hasXmlDom = document.implementation.hasFeature("XML","1.0");

6、文档写入

write(): 原样写入

writeln(): 在字符串的末尾添加一个换行符(n)

open(): 打开网页的输出流

close(): 关闭网页的输出流

// 用 write() 和 written() 动态地包含外部资源


    document.write() Example


    ");
    

严格型 XHTML 文档不支持文档写入。

Element 类型

Element 类型用于表现 XML 或 HTML 元素,提供了对元素标签名、字节点及特性的访问。

nodeType 的值为 1;

nodeName 的值为元素的标签名;

nodeValue 的值为 null;

parentNode 可能是 Document 或 Element;

其子节点可能是 Element、Text、Comment、ProcessingInstruction、CDATASection 或 EntityReference;

访问元素标签名,可以是使用 nodeName 属性或者 tagName 属性。

var div = document.getElementById("myDiv"); alert(div.tagName); // "DIV" alert(div.tagName == div.nodeName); // true

在 HTML 中,标签名始终都以全部大写表示;而在 XML(有时包括 XHTML),标签名始终与源代码中的保持一致。

if (element.tagName.toLowerCase() == "div") {    // 适用于任何文档
    // ...
}

1、HTML 元素

所有的 HTML 元素都由 HTMLElement 类型表示。每个 HTML 元素都存在的下列标准特性。

id,元素中文档中的唯一标识符

title,有关元素的附加说明信息,一般通过工具提示条现实出来

lang,元素内容的语言代码

dir,语言的方向,值为“ltr”(左到右),或“rtl”(右到左)

className,与元素的 class 特性对应,即为元素指定的CSS类。(是 ECMAScript 的保留字)

// 上述这些属性都可以用来取得或修改相应的特性值
var div = document.getElementById("myDiv"); alert(div.id); div.id = "someOtherId"; alert(div.className); div.className = "ft";

2、取得特性

每个元素都有一或多个特性,这些特性的用途是给出相应元素或其内容的附加信息。

getAttribute(): 取得特性,传递的特性名与实际的特性名相同,可以是自定义的特性。

setAttribute(): 设置特性。设置的特性名统一转为小写。

removeAttribute(): 不仅会清除特性值,也会从元素中完成删除特性。

有两类特殊的特性:

style: 通过getAttribute()访问返回特性值中包含的文本,通过属性来访问返回一个对象。

onclick: 通过 getAttribute()返回相应代码的字符串,访问属性时返回函数。

div.setAttribute("id","someOtherId");

3、attributes 属性

attributes 属性包含一系列节点,每个节点的 nodeName 就是特性的名称,而节点的 nodeValue 就是特性的值。
包含一个 NamedNodeMap,“动态”集合。

getNamedItem():返回 nodeName 等于 name 的节点

removeNamedItem():从列表中移除 nodeName 属性等于 name 的节点

setNamedItem():向类表添加节点,以节点的 nodeName 属性为索引

item(pos):返回位于数字pos 的节点

var id = element.attributes.getNamedItem("id").nodeValue;
var id = element.attributes["id"].nodeValue;

遍历元素的特性,attributes 属性可以派上用场。

function outputAttributes(element) {
    var pairs = new Array(),
        attrName,
        attrValue,
        y,
        len;
     
     for(y = 0, len = element.attributes.length; y < len; y++) {
         attrName = element.attributes[y].nodeName;
         attrValue = element.attributes[y].nodeValue;
         if (element.attributes[y].specified) {
             pairs.push(attrName + "="" + attrValue + """);
         }
     }
     return pairs.join(" ");
}

// attributes 对象的中的特性,不同浏览器返回的顺序不同
// IE7 及更早版本会返回 HTML 元素中所有可能的特性,包括没有指定的特性。每个特性节点都有一个 specified 的属性,true:在 HTML 中指定来相应特性,要么可以通过 setAttribute() 方法设置了该特性。

4、创建元素

// 接受一个参数,即要创建元素的标签名
var div = document.createElement("div");

// 也为新元素设置了 ownerDocument 属性,还可以操作元素的特性,添加更多的子节点
div.id = "myNewDiv";
div.className = "box";

// 新元素添加到文档树中 appendChild()、insertBefore()、replaceChild()
document.body.appendChild(div);

在 IE 中可以另一种方法,传入完整的元素标签

var div = document.createElement("
");

5、元素的子节点

不同浏览器看待节点是不同的。
如果要通过 childNodes 属性遍历子节点,不要忘了浏览器之间的区别,通常先检查一下 nodeType 属性

for (var y = 0, len = element.childNodes.length; y < len; y++) {
    // 表示是元素节点
    if (element.childNodes[y].nodeType == 1) {
        // ...
    }
}

通过特定的标签名取得子节点或后代节点

var ul = document.getElementById("myList");
var items = ul.getElementsByTagName("li");
Text 类型

文本节点由 Text 类型表示,包含纯文本内容,即包含转义后的 HTML 字符,但不包含 HTML 代码。

nodeType 的值为 3;

nodeName 的值为 “#text”;

nodeValue 的值为节点所包含的文本;

parentNode 是一个 Element;

不支持(没有)子节点;

通过 nodeValue 属性或 data 属性访问 Text 节点包含的文本。

appendData(text):将 text 添加到节点的末尾。

deleteData(offset, count):从 offset 指定的位置开始删除 count 个子符。

insertData(offset, text):在 offset 指定的位置插入 text。

replaceData(offset, count, text):用 text 替换从 offset 指定的位置开始到 offset + count 为止的文本。

splitText(offset):从 offset 指定的位置将当前文本节点分为两个文本节点。

substringData(offset, count):提取从 offset 指定的位置开始到 offset + count 为止的字符串。

在默认情况下,每个可以包含内容的元素最多只能有一个文本节点,而且必须确实有内容存在。

// 没有内容,也就没有文本节点
// 有空格,因而有一个文本节点
// 有内容,因而有一个文本节点
hello world!
// 访问,先取得引用 var textNode = div.firstChild; // 获取 div.childNodes[0] textNode.nodeValue = "some other message";

在修改文本节点时,此时的字符串会经 HTML 编码(转义)。

1、创建文本节点

document.createTextNode():创建文本节点,接受一个参数,要插入的文本,也会进行转义。

var element = document.createElement("div");
element.className = "message";

var textNode = document.createTextNode("Hello world");
element.appendChild(textNode);

var anotherTextNode = document.createTextNode("Yippee");
element.appendChild(anotherTextNode);

document.body.appendChild(element);

如果两个文本节点是相邻的同胞节点,那么这两个节点中的文本会连起来显示,中间不会有空格。

2、规范化文本节点

normalize():在一个包含两个或多个文本节点的父元素上调用,则会将所有文本节点合并成一个节点。

Comment 类型

nodeType 的值为 8;

nodeName 的值为 “#comment”;

nodeValue 的值是注释的内容;

parentNode 可能是 Document 或 Element;

不支持(没有)子节点。

和 Text 类型相似,可以通过 nodeValue 或 data 属性来取得注释的内容。

// 通过父节点访问 var div = document.getElementById("myDiv"); var comment = div.firstChild; alert(comment.data);

使用 document.createComment() 为其传递注释文本也可以创建注释节点。

var comment = document.createComment("A comment");

如果要访问注释节点,一定要保证他们是 元素的后代。

DocumentFragment 类型(文档片段)

在文档中没有对应的标记;

nodeType 的值为 11;

nodeName 的值为 “#document-fragment”;

nodeValue 的值为 null;

parentNode 的值为 null;

不能把文档片段直接添加到文档中,但可以作为一个“仓库”,保存将来可能添加到文档中的节点。如果将文档中的节点添加到文档片段中,就会从文档树移除该节点,文档片段本身不会成为文档树的一部分。

// 创建文档片段 
var fragment = document.createDocumentFragment();

// 为 ul 元素添加3个列表项
var ul = document.getElementById("myList");
var li = null;

for (var i=0; i < 3; i++) {
    li = document.createElement("li");
    li.appendChild(document.createTextNode("Item " + (i+1)));
    fragment.appendChild(li);
}

ul.appendChild(fragment);
Attr 类型

元素的特性在 DOM 中以 Attr 类型来表示。特性就是存在于元素的 attributes 属性中的节点。

nodeType 的值 2;

nodeName 的值是特性的名称;

nodeValue 的值是特性的值;

parentNode 的值为 null;

在 HTML 中不支持子节点;

在 XML 中子节点可以是 Text 或 EntityReference。

尽管是节点,但不是 DOM 文档树但一部分。有3个属性:

name:特性名称(与 nodeName 相同);

value:特性的值(与 nodeValue 的值相同);

specified:一个布尔值,区别特性在代码中是指定的,还是默认的。

// 创建
var attr = document.createAttribute("align");
attr.value = "left";
// 添加到元素中
element.setAttributeNode(attr);

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/96607.html

相关文章

  • 如何正确学习JavaScript

    摘要:然而,虽然先生对无所不知,被誉为世界的爱因斯坦,但他的语言精粹并不适合初学者学习。即便如此,在后面我还是会建议把当做补充的学习资源。但目前为止,依然是学习编程的好帮手。周正则表达式,对象,事件,阅读权威指南第,,,章。 既然你找到这篇文章来,说明你是真心想学好JavaScript的。你没有想错,当今如果要开发现代网站或web应用(包括互联网创业),都要学会JavaScript。而面对泛...

    canger 评论0 收藏0
  • 持续集成之测试篇

    摘要:持续集成单元测试是开源的一个基于的测试执行过程管理工具。表示测试套件,是一序列相关程序的测试表示单元测试,也就是测试的最小单位。 持续集成 单元测试(unit) karma Karma 是Google开源的一个基于Node.js 的 JavaScript 测试执行过程管理工具(Test Runner)。该工具可用于测试所有主流Web浏览器,也可集成到 CI (Continuous in...

    GraphQuery 评论0 收藏0
  • [译] 如何恰当地学习 JavaScript

    摘要:原文链接恰当地学习适合第一次编程和非的程序员持续时间到周前提无需编程经验继续下面的课程。如果你没有足够的时间在周内完成全部的章节,学习时间尽力不要超过周。你还不是一个绝地武士,必须持续使用你最新学到的知识和技能,尽可能地经常持续学习和提高。 原文链接:How to Learn JavaScript Properly 恰当地学习 JavaScript (适合第一次编程和非 JavaSc...

    Jason 评论0 收藏0
  • webpack 4.x学习使用总结

    摘要:最近一周一直都在折腾一些项目中常用的记录下来,以后免去简单的配置再去查文档。常规入口指示应该使用哪个模块,来作为构建其内部依赖图的开始。把代码转换成,在使用语言中有介绍。扩展语法,使用下一代,在使用中有介绍。用于忽略部分文件。 最近一周一直都在折腾webpack,一些项目中常用的记录下来,以后免去简单的配置再去查文档。 常规 1.入口 指示 webpack 应该使用哪个模块,来作为构建...

    ls0609 评论0 收藏0
  • 网页动画性能日志(一)

    摘要:当用户滚动页面时,合成线程会通知主线程更新页面中最新可见部分的位图。但是,如果主线程响应地不够快,合成线程不会保持等待,而是马上绘制已经生成的位图,还没准备好的部分用白色进行填充。 动画做多了,自然就要考虑性能,我打算出一个系列的日志,详细的讲解一下网页动画性能相关的知识,如果你已经可以运用css3 canvas来做动画,可以来参考一下。 目前我做的最复杂的动画就是360搜索中PC端的...

    zhiwei 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<