JavaScript学习 八、DOM扩展

对DOM的两个主要扩展是Selectors API(选择符API)和HTML5.这两个扩展都是源自开发社区。此外还有一个不那么因为瞩目的ELement Traversal(元素遍历)规范。为DOM添加了一些属性。

选择符API

众多JavaScript 库中最常用的一项功能,就是根据CSS选择符选择与某个模式匹配的DOM元素。 实际上 jQuery 的核心就是通过CSS选择符查询DOM 文档取得元素的引用,从而抛开了 getElementById() 和 getElementsByTagName()。

selectors API Level 1 的核心是两个方法:querySelector() 和 querySelectorAll()。在兼容的浏览器中,可以通过Document 及 Element 类型的实例调用它们。目前已经完全支持 Selectors API Level 1的浏览器有 IE 8+、Firefox 3.5+、Safari 3.1+、Chrome 和 Opera 10+。

querySelector() 方法接收一个CSS 选择符,返回与该模式匹配的第一个元素,如果没有找到匹配的元素,返回null。

querySelectorAll() 方法也是接收一个CSS 选择符,返回一个NodeList 类型的实例。

上面两个方法如果传入了浏览器不支持的选择符或者选择符中有语法错误,则会抛出错误。

元素遍历

对于元素之间的空格,IE9及之前的版本不会返回文本节点,而其他所有浏览器都会返回文本节点。这样就导致了在使用childNodes 和 fristChild 等属性时的行为不一致。为了弥补这一差异,而同时有保持DOM规范不变,Element Traversal 规范 新定义了一组属性。

Element Traversal API 为DOM 元素添加了以下 5个属性。

  • childElementCount:返回子元素(不包括文本节点和注释)的个数。
  • firstElementChild:指向第一个子元素;firstChild 的元素版。
  • lastElementChild:指向最后一个子元素;lastChild的元素版。
  • previousElementSibling:指向前一个同辈元素;previousSibling 的元素版。
  • nextElementSibling:指向后一个同辈元素;nextSibling 的元素版。

支持Element Traversal 规范的浏览器有 IE9+、 Firefox3.5+、Safari 4+、Chrome 和 Opera 10+。

HTML5

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

与类相关的扩充

class 属性在 HTML文档中应用越来越多,一方面可以通过它为元素添加样式,另一方面还可以用它表示元素的语义。为了简化CSS类的用法,HTML5新增了很多相关的API。

1.getElementsByClassName() 方法

可以通过document对象及所有HTML 元素调用该方法。该方法接收一个参数,即一个包含一个或多个类名的字符串,返回带有指定类的所有元素的NodeList。传入多个类名是,类名的先后顺序不重要。

var allCurrentUserNames = document.getElementsByClassName("username current");

var selected = document.getElementById("myDiv").getElementsByClassName("selected");

支持getElementsByClassName() 的浏览器有 IE9+、 Firefox3+、Safari 3.1+、Chrome 和 Opera 9.5+。

2.classList 属性

由于calssName 中是一个字符串,所以如果想删除或修改某个类名时,就要分析整个字符串,方法如下:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>study</title>
    </head>
    <body>
        <div class="bd user disabled">testdiv</div>
        <script type="text/javascript">
        var allDiv = document.getElementsByClassName("disabled bd");
        var div = allDiv[0];

        var classNames = div.className.split(/\s+/);
        //find className
        var pos = -1, i, len;
        for(i=0, len=classNames.length; i<len; i++){
            if(classNames[i] == "user"){
                pos = i;
                break;
            }
        }

        //delete className
        classNames.splice(i, 1);

        //join
        div.className = classNames.join(" ");
        </script>
    </body>
</html>

HTML5 新增了一个操作类名的方式,可以让操作更加简单也更安全,那就是为所有元素添加了classList 属性。这个classList 属性是新集合类型 DOMTokenList 的实例,与其他集合一样,DOMTokenList 有一个表示自己包含多少元素的 length 属性,而要取得每个元素可以使用 item() 方法,也可以又使用方括号语法。另外这个新类型还有如下方法:

  • add(value):将给定的字符串值添加到列表中。如果值已经存在就不添加了。
  • contains(value):表示列表中是否存在给定的值,如果存在则返回true,否则返回false。
  • remove(value):从列表中删除给定的字符串。
  • toggle(value):如果列表中已经存在给定的值,则删除它;如果没有,则添加它。

所以上例中的一坨代码就可以简化成一条:

div.classList.remove("user");

支持classList 属性的浏览器有 Firefox3.6+ 和 Chrome。

焦点管理

HTML5 中添加了辅助管理DOM焦点的功能,首先就是 document.activeElement 属性,这个属性始终会引用DOM中当前获得了焦点的元素。元素获得焦点的方式有页面加载、用户输入(通常是通过按Tab键)和在代码中调用 focus() 方法。

var button = document.querySelector("#mybutton");
button.focus();
alert(document.activeElement == button);  //true

默认情况下,文档刚刚加载完成时,document.activeElement 中保存的是 document.body 元素的引用。文档加载期间,document.activeElement 的值是 null。

另外新增了 document.hasFocus() 方法,这个方法用于判确定文档是否获得了焦点。

实现了者两个属性的浏览器包括 IE4+、Firefox 3+、Safari 4+、 Chrome 和 Opera 8+。

HTMLDocument 的变化

HTML5 扩展了 HTMLDocument,增加了新的功能。

1.readyState 属性

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

  • loading,正在加载的文档;
  • complete,已经加载完文档。

使用document.readyState 的最恰当的方式,就是通过它来实现一个指示文档已经加载完成的指示器。

支持readyState 属性的浏览器有 IE4+、Firefox3.6+、Safari 、Chrome 和 Opera 9+ 。

2.兼容模式

document.compateMode 的 值等于 “CSS1Compat”表示浏览器在标准模式下。document.compatMode 值等于“BackCompat” 表示浏览器在混杂模式下。

3.head属性

类似于 document.body HTML5 增加了 document.head 属性来引用文档的 <head> 元素。可以结合使用这个属性和另一种后备方法。

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

4.自定义数据属性

HTML5规定可以为元素添加非标准的属性,但是要添加前缀 data-,目的是为元素提供与渲染无关的信息,或者提供语义信息。这些属性可以任意添加、随便命名,只要以data- 开头即可。

添加了自定义属性之后,可以通过元素的dataset 属性来访问自定义属性的值。dataset 属性的值是一个DOMStringMap 的实例,也就是一个名值对儿的映射。在这个映射中,每个data-name 形式的属性都会有一个对应的属性,只不过属性名没有 data- 前缀。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>study</title>
    </head>
    <body>
        <button id="mybutton" data-apptype="iphone" data-myname="AJ">pushme</button>
        <script type="text/javascript">
        var button = document.querySelector("#mybutton");
        var appType = button.dataset.apptype;
        var myname = button.dataset.myname;
        alert(appType + "  "  + myname);

        button.dataset.apptype = "Android";
        button.dataset.myname = "LL";

        if(button.dataset.myname){
            alert("Hello " + button.dataset.myname);
        }

        </script>
    </body>
</html>

注意:以上代码中 dataset 后面的属性不可以用大写,因为HTML中属性都会被变成小写,所以JavaScript 中也必须使用小写才能访问。

支持自定义数据属性的浏览器有Firefox 6+ 和 Chrome。

5.插入标记

innerHTML属性返回与调用元素的所有子节点对应的HTML标记,写入innerHTML 时会根据指定的值创建新的DOM树,然后用这个DOM树完全替换调用元素原先所有的子节点。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>study</title>
    </head>
    <body>
        <div id="content">
            <p>This is a <strong>paragraph</strong> with a list following it.</p>
            <ul>
                <li>1</li>
                <li>2</li>
                <li>3</li>
            </ul>

        </div>
        <script type="text/javascript">
            var div = document.getElementById("content");
            alert(div.innerHTML);
            /**
            <p>This is a <strong>paragraph</strong> with a list following it.</p>
            <ul>
                <li>1</li>
                <li>2</li>
                <li>3</li>
            </ul>
            */
            div.innerHTML = "Hello World!";
        </script>
    </body>
</html>

outerHTML属性,返回调用它的元素及所有子节点的HTML标签。在写入的情况下,outerHTML会根据指定的HTML 字符串创建新的DOM子树,然后用这个DOM子树完全替换调用的元素。

6. scrollIntoView() 方法

scrollIntoView() 可以在所有 HTML元素上调用,通过滚动浏览器窗口或者某个容器元素,调用元素就可以出现在视口中。如果给这个方法传入true 作为参数,或者不传入任何参数,那么窗口滚动之后会然调用元素的顶部与视口顶部尽量平齐。如果传入false 作为参数,调用元素会尽可能全部出现在视口中。不过顶部不一定平齐。

document.forms[0].scrollIntoView(); 

专有扩展

1.children 属性

children属性是一个HTMLCollection 实例,值包含元素重同样还是元素的子节点,除此之外 children 和 childNode没有什么区别,即在元素值包含元素子节点时,者两个属性的值相同。

2.contains() 方法

contains 方法用于确定某个节点(参数)是不是被检测节点的后代节点。是则返回true 否则返回false。

除此之外还可以使用 DOM Level 3 中的 compareDocumentPosition() 方法来确定节点之间的关系。返回一个表示该关系的位掩码(bitmask)。掩码值如下:

  • 1:无关(给定的节点不在当前文档中)
  • 2:居前(给定的节点在DOM树中位于参考节点之前)
  • 4:居后(给定的节点在DOM树中位于参考节点之后)
  • 8:包含(给定的节点是参考节点的祖先)
  • 16:被包含(给定的节点是参考节点的后代)

一个通用的contains() 函数可以写成如下形式:

function contains(refNode, otherNode){
    if(typeof refNode.contains == "function" &&
        (!client.engine.webkit || client.engine.webkit>522)){
        return refNode.contains(otherNode);
    }else if(typeof refNode.compareDocumentPosition == "function"){
        return !!(refNode.compareDocumentPosition(otherNode) & 16);
    }else{
        var node = otherNode.parentNode;
        do{
            if(node == refNode){
                return true;
            }else{
                node = node.parentNode;
            }
        }while(node != null);
        return false;
    }
}

小结

虽然DOM 为与XML及HTML 文档交互制定了一系列核心API,但仍然有几个规范会标准的DOM进行了扩展。这些扩展中有很多原来是浏览器转悠的,但后来成为了事实标准,于是其他浏览器也都提供了相同的实现。

  • Selectors API,定义了两个方法,让开发人员能够基于CSS选择符从DOM 中取得元素,这两个方法是 querySelector() 和 querySelectorAll()。
  • Element Traversal,为DOM元素定义了额外的属性,让开发人员能够更方便地从一个元素跳到另一个元素。之所以会出现这个扩展,是因为浏览器处理DOM元素间空白符的方式不一样。
  • HTML5, 为标准的DOM 定义了很多扩展功能。其中包括在innerHTML属性这样的事实标准基础上提供的标准定义,以及为管理焦点、设置字符集、滚动页面而规定的扩展API。
时间: 2024-10-15 09:53:01

JavaScript学习 八、DOM扩展的相关文章

JavaScript学习--Item29 DOM基础详解

看完JavaScript高级程序设计,整理了一下里面的DOM这一块的知识点,比较多,比较碎!DOM在整个页面的地位如图: DOM(文档对象模型)是针对HTML 和XML 文档的一个API(应用程序编程接口).DOM描,绘了一个层次化的节点树,允许开发人员添加.移除和修改页面的某一部分. 1.节点层次 DOM 可以将任何HTML 或XML 文档描绘成一个由多层节点构成的结构.节点分为几种不同的类型,每种类型分别表示文档中不同的信息及(或)标记.每个节点都拥有各自的特点.数据和方法,另外也与其他节点

JavaScript学习笔记——DOM基础 2.5

一.document.write方法 document对象write()方法,常用来向网页中输出字符串,圆括号中可以是要输出的字符串, document.write('这是我的个人博客'); 也可以是字符串变量, var myText = '这是我的个人博客'; document.write(myText); 还有一种,就是通过字符串和变量组合的方式进行输出. var myText = '这是我的'; document.write(myText + '个人博客'); document.write

JavaScript学习笔记——DOM基础 2.1

一.DOM 1.DOM的基本概念 DOM是Document Object Model的缩写,意思是文本对象模型,也就是说,如果没有Document,DOM也就无从谈起.我们可以把创建的网页当作是一个Document对象. JavaScript的对象可以分为三种类型:由用户自定义的对象,由JavaScript本身提供的内建对象,以及由浏览器提供的宿主对象. 顺便提一下BOM(Browser Object Model)和WOM(Window Object Model),其实这两个说的是一种东西,但大

Javascript学习总结-DOM编程-(七)

1. DOM 1.1. DOM简介 全称Document Object Model,即文档对象模型. DOM描绘了一个层次化的树,允许开发人员添加.删除.修改页面的某一部分. 浏览器在解析HTML页面标记的时候,其实不是按照一行一行读取并解析的, 而是将HTML页面中的每一个标记按照顺序在内存中组建一颗DOM树, 组建好之后,按照树的结构将页面显示在浏览器的窗口中. 1.2. 节点层次 HTML网页是可以看做是一个树状的结构,如下: html |-- head |     |-- title |

JavaScript学习笔记——DOM基础 2.6

一.CSS-DOM 1.清楚一个概念 HTML负责的是结构,CSS负责的是样式,JavaScript负责的是动作(行为). 2.style属性 语法:element.style 返回:object style相对于element是一个属性,而style本身是一个对象,它包含了诸多元素的样式. 关于这一点,可以根据后面的例子去理解. 3.获取样式 例子:element.style.fontFamily 返回:style对应属性的值,如fontFamily,返回“Microsoft yahei” 注

javascript学习笔记DOM(2)

DOM DOM元素的类型 节点类型          节点名称        节点值 nodeType      nodeName      nodeValue    元素节点        文本节点          注释节点      documentnodeType              1    3  8  9 nodeName       大写的标签名      #text         #comment    #document nodeValue    null      

JavaScript学习笔记——DOM对象

javascript-document对象详解 DOM document(html xml) object modledocument对象(DOM核心对象) 作用: 1.内容 innerHTML 2.属性 3.样式 document对象 一.属性 title 返回或设置当前文档的标题 URL 返回当前文档的url bgColor 设置文档的背景色 fgColor 设置文档的前景色(设置文字颜色) 二.方法 getElementById(idname) 返回拥有指定id的(第一个)对象的引用 ge

javascript学习笔记DOM(1)

DOM DOM我个人理解就是网页中的每一个元素,如果把每一个节点和子节点以树形结构表示出来很像家里的族谱图,如下图. 所以DOM关系也可以看成是描述网页元素关系的“族谱图”,只要知道其中一个人就可以找到任何一个跟他有直接或者间接关系的人,(例如:你想找你的二大爷,可以找到你爸爸的二哥就可以了,要是指向的是隔壁老王的二哥就出事儿了.).DOM关系也是一样,知道其中一个就可以根据他们的关系来找到任何一个DOM元素. 获取元素的方法有哪些? 1.document.getElementById("Id&

JavaScript学习笔记(十一)---- DOM扩展

(一)DOM扩展 对DOM的主要的扩展是SelectorsAPI(选择符API)和HTML5,还有一个Element Travesal规范. 1.选择符API jQuery的核心就是通过CSS选择符查询DOM文档取得元素的引用,从而抛开了getElementById( ) 和 getElementsByTagName( ). Selectors API Level 1的核心是两个方法:querySelector( )和 querySelectorAll( ). querySelector( ):