虽然DOM为XML及HTML文档交互制定了一系列的API,但仍然有几个规范对标准的DOM进行了扩展。这些扩展中,有很多是浏览器专有的,但后来成了事实标准,于是其他浏览器也提供了相同的实现;浏览器开发商发现某项功能缺失时,仍然会直接往DOM中添加专有扩展,以弥补不足。下面分别介绍这些标准扩展和专有扩展。

一、选择符API

  选择符API的功能是根据CSS选择符选择与某个模式匹配的DOM元素。Jquery的核心就是通过CSS选择符查询DOM文档以取得元素的引用,从而抛开了getElementById()和getElementsByTagName()。选择符API是W3C发起的一个标准,目的是让浏览器支持原生支持CSS查询。它的核心方法是querySelector(),querySelectorAll()和matchesSelector()。

  querySelector()接受一个CSS选择符,返回与该模式匹配的的第一个字符。

  1. //取得body元素
  2. var body = document.querySelector("body");
  3.  
  4. // 取得ID为“myDiv"的元素
  5. var myDiv = document.querySelector("#myDiv");
  6.  
  7. // 取得类名为 ”selected"的第一个元素
  8. var selected = document.querySelector(".selected");
  9.  
  10. // 取得类名为“button"的第一个图像元素
  11. var img = document.querySelector("img.button");

  querySelectorAll()返回的是所有匹配的元素而不仅仅是一个元素,即一个NodeList的实例。

  1. // 取得div中的所有<em>元素
  2. var ems = document.getElementById("myDiv").querySelectorAll("em");
  3. // 取得类为selected的所有元素
  4. var selectors = document.querySelectorAll(".selected");
  5. // 取得所有<p>元素中的<strong>元素
  6. var strongs = document.querySelectorAll("p strong");

  matchesSelector()如果调用元素与选择符匹配,返回true;否则,返回false。不过,由于不是所有的浏览器都支持这个方法,我们需要写一个包装函数:

  1. function matchesSelector(element, selector){
  2. if(element.matchesSelector){
  3. return element.matchesSelector(selector);
  4. }else if(element.msMatchesSelector){
  5. return element.msMatchesSelector(selector);
  6. }else if(element.mozMatchesSelector(selector)){
  7. return element.mozMatchesSelector(selector);
  8. }else if(element.webkitMatchesSelector(selector)){
  9. return element.webkitMatchesSelector(selector);
  10. }else{
  11. throw new Error("Not supported.");
  12. }
  13. }

二、元素遍历

  对于元素间的空格,IE9以及之前的版本不会返回文本节点,而其他浏览器都会返回文本节点。由于浏览器的行为不一致,W3C为元素添加了以下几个新属性:

  1. childElementCount: 返回子元素的个数,不包括文本节点和注释节点
  2. firstElementChild: 指向第一个子元素,firstChild的元素版
  3. lastElementChild:指向最后一个子元素,lastChild的元素版
  4. previousElementSibling:指向前一个同辈元素,previousSibling的元素版
  5. nextElmnetSibling:指向后一个同辈元素,nextSibling的元素版

使用这些属性,可以不必担心空白字符,从而更方便的查找DOM元素了。下面比较使用过去的方法和使用新增元素的代码:

  1. var i,
  2. len,
  3. child = element.firstChild;
  4. while(child != element.lastChild){
  5. if(child.noteType == 1){
  6. processChild(child);
  7. // 检查是否是元素节点
  8. }
  9. child = child.nextSibling;
  10. }
  1. var i,
  2. len,
  3. child = element.firstElementChild;
  4. while(child != element.lastElementChild){
  5. if(child.noteType == 1){
  6. processChild(child);
  7. }
  8. child = child.nextElementSibling;
  9. }

三、HTML5

  HTML5围绕如何使用新增标记定义了大量的JAVASCRIPT API,其中一些API与DOM重叠,定义了浏览器应该支持的DOM扩展。

1、与类相关的扩充

  1. <html>
  2. <head></head>
  3. <body>
  4. <div id="test" class="username current"></div>
  5. <div id="test1" class="current username"></div>
  6. <script>
  7. // 取得所有类中包含”usrname"和“current”的元素的,类名的先后无所谓
  8. var allCurrentUsernames = document.getElementsByClassName("username current");
  9.  
  10. var div = document.getElementById("test");
  11. // 删除元素中的类
  12. div.remove("username");
  13.  
  14. // 添加类
  15. div.add("username");
  16.  
  17. // 切换类:如果已经存在,就删除它;如果不存在,就添加它
  18. div.toggle("username");
  19.  
  20. // 确定元素中是否包含类
  21. div.contains("username");
  22. </script>
  23. </body>
  24. </html>

2、焦点管理

  确认用户是否获得了焦点,可以知道用户是否正在交互。

  1. var button = document.getElementById("myButon");
  2. button.focus();
  3. alert(document.hasFocus()); //true

3、HTMLDocument的变化

1)Document的readyState属性有两个可能的值:

loading,正在加载文档;

complete,已经加载完文档了。

2)从IE6就开始区分渲染页面的模式是标准的还是混杂的,检测页面的兼容模式就成了浏览器的必要功能。使用document.compatMode表示渲染模式,在标准模式下,这个值等于“CSS1Compat”,在混杂模式下,这个值等于“BackCompat”。

3)作为对document.body是引用文档的<body>元素的补充,HTML5新增了document.head元素,用于表示文档的<head>元素:

  1. var head = document.head || document.getElementsByTagName("head")[0];

4、字符集属性

HTML5新增了几个与文档字符集相关的属性,document.charset表示文档中实际使用的字符集,也可以用来表示新的字符集;document.defaultCharset表示根据默认浏览器及操作系统的设置,当前文档默认的字符集应该是什么。

5、自定义数据属性

  如果需要给元素添加一些不可见的数据以便进行其他处理,那就要用到自定义数据属性;自定义属性需要添加前缀“data-”,目的是为元素提供与渲染无关的信息,或者提供语义信息。

6、插入标记

  虽然DOM为操作节点提供了细致入微的控制手段,但需要给文档插入大量HTML标记的情况下,通过DOM操作仍然非常困难,因为不仅需要创建一系列的DOM节点,还要小心的按照正确的顺便把它们连接起来。而使用插入技术,直接插入HTML字符会简单很多。

1)innerHTML

  innerHTML在读模式下,会返回与调用元素的所有子节点(包括元素、注释和文本节点)对应的HTML标记。在写模式下,会根据指定的值创建新的DOM树,然后用DOM树完全替换元素原先的子节点。

2)outerHTML

  outerHTML在读模式下,会返回调用元素自身以及所有的子节点对应的HTML标记。在写模式下,会根据执行的值创建新的DOM树,然后用DOM完全替换自身以及子节点。

3)insertAdjacentHTML()

  这个方法接受两个参数,插入位置和要插入的文本,第一个参数必须是下列值之一:

  • beforebegin:在调用元素之前插入一个相邻的同辈元素
  • afterbegin:作为调用元素的第一个子元素插入
  • beforeend:作为调用元素的最后一个子元素插入
  • afterend:作为调用元素的最后一个同辈元素插入

7、内存与性能问题

  替换或删除节点,可能会导致浏览器的内存占用问题:当把某个元素从文档树中删除后,元素与事件处理程序之间的绑定关系并没有删除。如果这种情况频繁出现,页面占用内存数就会明显增加。因此,在使用innerHTML/outerHTML/insertAdjacentHTML之前,最好先手工删除要被替换的元素的所有事情处理程序和javascript对象属性。

8、scrollIntoView()

  scrollIntoView()可以在所有的HTML元素上调用,如果给这个方法传入true做参数,或者不传入任何参数,那么窗口滚动之后,会尽量让调用元素的顶部与视口的顶部保持齐平。如果传入false作参数,调用元素会尽可能全部出现在视口中。

三、专有扩展

  虽然所有的浏览器厂商都知道坚守标准的重要性,但在发现某项功能缺失时,仍然会一如既往的在DOM中添加专有扩展,以弥补功能上的不足;这些扩展一旦获得认可,就有可能被收录到规范的新版本中。以下介绍一些专有扩展:

1、文档模式

  文档模式是IE引入的概念,页面的文档模式决定了文档可以使用哪个级别的CSS,可以在Javascript中使用哪些API,以及如何对待文档类型(doctype)。

2、contains方法

  contains方法用于判断一个节点是否是调用节点的子节点。

3、插入文本

1)innerText属性

  通过innerText属性,可以操作元素中所有包含的文本节点。

  1. <html>
  2. <head></head>
  3. <body>
  4. <div id="content">
  5. <p>This is a paragragh.</p>
  6. <ul>
  7. <li>item 1</li>
  8. <li>item 2</li>
  9. <li>item 3</li>
  10. </ul>
  11. </div>
  12. </body>
  13. </html>

对这个例子而言,innerText会返回:

  • This is a paragragh.
  • item 1
  • item 2
  • item 3

  如果通过innerText设置文本,则会先删除调用元素下所有的子节点,再添加上文本节点;即完全改变了dom树。

2)outerText

  在读模式下,outerText与innerText完全一致,在写模式下,outerText会先删除调用节点本身以及子节点,再添加上文本节点。

《JAVASCRIPT高级程序设计》DOM扩展的更多相关文章

  1. 11. javacript高级程序设计-DOM扩展

    1. DOM扩展 1.1 选择符API l querySelector() 接收一个css选择符,返回与该模式匹配的第一个元素 l querySelectorAll() 接收一个css选择符,返回所有 ...

  2. javascript高级程序设计---DOM

    DOM是文档对象模型的简称,DOM的基本思想是把结构化文档解析成一系列的节点,由这些节点组成数装的DOM树,所有的这些节点和最终的树状结构都有统一的对外接口,达到使用编程语言操作文档的目的,DOM可以 ...

  3. 2020/6/11 JavaScript高级程序设计 DOM

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

  4. 【javascript学习——《javascript高级程序设计》笔记】DOM操作

    DOM(文档对象模型)是针对HTML和XML文档的一个API(应用程序编程接口).DOM描绘了一个层次节点树,允许开发人员添加.移除和修改. 1.节点层次 <html> <head& ...

  5. 《JavaScript高级程序设计(第3版)》阅读总结记录第一章之JavaScript简介

    前言: 为什么会想到把<JavaScript 高级程序设计(第 3 版)>总结记录呢,之前写过一篇博客,研究的轮播效果,后来又去看了<JavaScript 高级程序设计(第3版)&g ...

  6. javascript高级程序设计阅读笔记(一)

    javascript高级程序设计阅读笔记(一) 工作之余开发些web应用作为兴趣,在交互方面需要掌握javascript和css.HTML5等技术,因此读书笔记是必要的. javascript简介 J ...

  7. 《JavaScript高级程序设计》学习笔记

    系统学习JS, 从<JavaScript高级程序设计>入门,通过学习jQuery或者angularJS源码来进阶. 第1章 JavaScript简介 1.JS问世的目的是处理以前由服务器端 ...

  8. 读书时间《JavaScript高级程序设计》一:基础篇

    第一次看了<JavaScript高级程序设计>第二版,那时见到手上的书,第一感觉真是好厚的一本书啊.现在再次回顾一下,看的是<JavaScript高级程序设计>第三版,并记录一 ...

  9. JavaScript高级程序设计(读书笔记)(一)

    本笔记汇总了作者认为“JavaScript高级程序设计”这本书的前七章知识重点,仅供参考. 第一章 JavaScript简介 JavaScript发展简史: 1995年,JavaScript诞生 19 ...

  10. javascript 高级程序设计 一

    前言: 作为一个即将毕业.正在实习的大学生,我也默默的进入了开发者的行列.从一开始的c#编码狗到java程序员再到现在的JS开发者,我一直 希望自己可以在这个'万恶'的互联网时代走的更远.但是我还是一 ...

随机推荐

  1. [iOS]C语言技术视频-10-指针变量

    下载地址: 链接: http://pan.baidu.com/s/1jGjbaXg 密码: u2t9

  2. sping 对 hibernate进行事务管理--Annotation, xml, 大多数使用XML

    1. UserServiceTest.java: package com.bjsxt.service; import org.junit.Test; import org.springframewor ...

  3. 使用USBASP给Arduino烧写bootloader教程

    源:使用UsbAsp给UNO烧写bootloader ATMEGA16U2.ATMEGA328P固件烧写教程 arduino板由于操作不发导致固件损坏,或者想更新固件怎么办?今天给大家介绍一下如何使用 ...

  4. HDU 5652 India and China Origins

    二分答案+验证,注意一开始就不连通的话输出0 #include<cstdio> #include<cstring> #include<cmath> #include ...

  5. JVM线程安全

    一.线程的调度方式 线程调度分为两种方式: 协同式调度和抢占式调度.协同式调度:线程的执行时间由线程本身控制,线程将工作执行完之后,通知操作系统切换到其他线程上.缺点:时间不可控,就算出问题,也不会通 ...

  6. 【bzoj1552】[Cerc2007]robotic sort

    题目描述 输入 输入共两行,第一行为一个整数N,N表示物品的个数,1<=N<=100000.第二行为N个用空格隔开的正整数,表示N个物品最初排列的编号. 输出 输出共一行,N个用空格隔开的 ...

  7. [转]SQL Server® 2008 R2 Express 静默安装

    1. http://msdn.itellyou.cn/下载Express版SQL Server 2.快捷键win+R,进入CMD,解压文件,解压命令为 <文件名>.exe /x <解 ...

  8. Android源码编译jar包BUILD_JAVA_LIBRARY 与BUILD_STATIC_JAVA_LIBRARY的区别(二)

    上文简单介绍了BUILD_JAVA_LIBRARY 与BUILD_STATIC_JAVA_LIBRARY编译出来jar包的区别, 那么你如果拿到了一个内容是dex格式的jar包,而你又偏偏需要这个ja ...

  9. hisi出的H264码流结构

    hisi出的H264码流结构: IDR帧结构如下: 开始码 + nalu + I帧    +    开始码 + nalu + SPS    +     开始码 + nalu + PPS    +    ...

  10. MongoDB升级教程

    1.排序 sort()方法:其中 1 为升序排列,而-1是用于降序排列. db.col.find({},{"title":1,_id:0}).sort({"likes&q ...