JavaScript DOM扩展

来源:互联网 发布:淘宝联盟转链工具 编辑:程序博客网 时间:2024/06/06 01:49

DOM扩展的两个主要方面包括选择符API和HTML5;

Selectors API Level 1定义了两个核心方法:querySelector()和querySelectorAll(),参数可以为class/ id/ 标签名等,可以通过Document和Element实例调用querySelector(),可以通过Document、DocumentFragment、Element调用querySelectorAll(),支持的浏览器包括IE8+、Chrome、FireFox 3.5+、safari 3.1+等;

元素遍历

Element Traversal API为DOM添加了下列五个属性(这些属性都不会受空白文本节点影响):
1、childElementCount: 返回子元素个数(不包括文本和注释节点);
2、firstElementChild/ firstChild: 指向第一个子元素;
3、lastElementChild/ lastChild: 指向最后一个子元素;
4、previousElementSibling/ previousSibling: 指向前一个兄弟元素;
5、nextElementSibling/ nextSibling: 指向后一个兄弟元素;

支持该规范的浏览器包括IE9+、Chrome、FireFox 3.5+;


HTML5

类扩展

getElementsByClassName()方法参数为一个包含多个与顺序无关类名的字符串,返回值为传入类名对应元素的NodeList,所以也需要注意其动态特性;可以通过document或者HTML元素调用该方法;
支持的浏览器有IE9+、Chrome、FireFox 3+

为了更加方便类名的操作,HTML5为所有元素新增了classList属性,该属性是新集合类型DOMTokenList的实例,具有length属性和item()方法;另外具有操作类名的add()/ remove()/ toggle()/ contains()方法用于类名的增删查;
这里写图片描述


焦点管理

HTML5新增。可以通过document.activeElement取得当前获取焦点的元素;元素获取焦点的方式:页面加载、用户输入(Tab键等)和使用focus()方法;document.activeElement在文档加载时值为null,加载完成时 document.activeElement === document.body;
还有一个无参方法document.hasFocus() 返回值为布尔值,用于确认文档是否获焦;

支持上述属性和方法的浏览器包括IE4+,兼容性很高;


HTMLDocument变化

1、标准化readyState,用于标示文档是否加载完成; IE4+等, 兼容性很好;
状态分别为uninitialized (未初始化)、loading(加载中)、interactive (已加载并解析,可以与用户交互,但图片等资源还未加载)、complete(文档加载完成);

2、兼容模式:IE6开始区分页面渲染的方式为标准模式还是混杂模式(怪诞模式),由IE引入的document.compatMode在HTML5中标准化,取值为CSS1Compat和BackCompat;

3、head属性:引入document.head引用<head>, 支持的浏览器为IE9+、Chrome 4.0、FireFox 4.0 Safari 5.0等;

4、自定义属性:HTML5中提供了使用data-前缀为元素添加自定义属性的方法,可以为元素提供与渲染无关的语义化信息,属性名可以随便命名;可以通过dataset(DOMStringMap的实例)属性取得这些自定义属性值;

该方法兼容性一般,支持的浏览器包括IE11+、FireFox 6.0+、Safari 6、Chrome 8等;

// html<div id="myDiv" data-myName="fn"></div>// JSvar node = document.getElementById("myDiv");var myName = node.dataset.myName;   // 获取自定义属性node.dataset.myName = "newName";    // 设置自定义属性

插入标记

innerHTML、outerHTML均具有读写模式,在处理<script>和<style>元素时具有一定的特殊性; insertAdjacentHTML()方法的第一个参数可以取值为“beforebegin”/ “beforeend”/ “afterbegin”/ “afterend”四个值;beforebegin和afterend两个值表示插入同辈元素,其他两个插入的是子元素;

element.insertAdjacentHTML(refer, content);

支持的浏览器包括IE、FireFox 8+、Safari、Chrome等;

使用这些方法尤其innerHTML可以比通过DOM操作创建这些相互关系高效很多,它在每次设置值时都会动态创建一个基于浏览器级别(C语言)的HTML解析器,比JS执行得更快;因此要控制好更改这些值的次数;

使用上述几个方法由于不会一并修改绑定的JS属性和相应的事件处理程序,因此可能会带来相应的内存和性能问题;可以在调用这些方法前先手动删除这些属性或事件;

element.scrollIntoView()方法:可以应用到整个HTML元素,用于调整元素的位置,该方法可以接受一个布尔值,传入true则表示视口顶部与元素顶部对齐,false则使元素尽可能出现在视口中;

专有扩展

文档模式:

文档模式决定了浏览器如何解析页面,限制了可以使用的CSS级别,JS API等;

理解文档模式可以更好的理解浏览器的工作原理;
通过设置<meta>标签或者HTTP头部信息为X-UA-Compatible,强制浏览器以某种方式渲染页面;

<meta http-equiv="X-UA-Compatible" content="IE=Edge">   // 以最新文档模式渲染页面
    // 通用的元素包含关系判断函数    function contains (containerNode, containedNode) {        if (typeof containerNode.contains === 'function') {            return containerNode.contains(containedNode);        } else if (typeof compareDocumentPosition === 'function') {            return containerNode.compareDocumentPosition(containedNode);        } else {            var node = containedNode.parentNode;            while (node !== null) {                if (node === containerNode) {                    return true;                } else {                    node = node.parentNode;                }            }        }    }


DOM2

DOM2样式属性和方法

标准模式下,所有度量值必须指定度量值;DOM2样式定义的属性和方法:
cssText(string),string表示样式字符串;
length: CSS属性数量;
item(index):访问css某个属性;
getPropertyValue(prop):获取特定属性的值;
setProperty(prop, value, priority): 设置属性名、属性值及优先级;
removeProperty(prop):移除特定属性;

支持的浏览器包括IE9+、FireFox、Chrome等;

计算样式

DOM2 级样式提供了document.defaultView.getComputedStyle()方法,第一个参数为要取得计算样式的元素,第二个参数为伪元素字符串,可以为null;该方法返回的是一个CSSStyleDeclaration对象,包含了所有的计算样式;
这里写图片描述

在浏览器中,所有的计算样式都是只读的;IE不支持getComputedStyle()方法,但是有相同功能的currentStyle属性;

元素大小

不属于DOM2级样式规范;

这些偏移量属性都是只读的,每次访问会重新计算;
这里写图片描述

这里写图片描述

clientWidth和clientHeight: 元素内容区+两个内边距宽度;区别与offsetWidth和offsetHeight,它们不包含滚动条;客户区的这些属性只是可读的;

浏览器视口大小确定:
这里写图片描述

这里写图片描述


遍历

DOM2 提供了两个用于 深度优先遍历 DOM的类型:NodeIterator和TreeWalker。
IE8不支持DOM遍历;IE9完全支持

DOM2 遍历能力检测

// DOM2级 遍历支持检测var supportTraversal = document.implementation.hasFeature('Traversal', '2.0')var supportNodeIterator = typeof document.createNodeIterator === 'function';var supportTreeWalker = typeof document.createTreeWalker === 'function';

1、NodeIterator:
NodeIterator的nextNode()和previousNode()方法用于遍历,创建NodeIterator实例后第一次调用nextNode()会指向遍历的根节点,遍历到最后一个节点时返回null;
使用document.createNodeIterator(root, nodeType, filter, entityReferenceExpansion)方法可以创建对应实例;方法接收四个参数,分别为根节点、常量表示的节点类型、NodeFilter对象或类似函数、表示扩展实体引用的布尔值(html中为false)。
NodeFilter对象仅有一个acceptNode()方法用于接收或拒绝访问某个节点;

// 第三个参数的设置var filter = {    acceptNode: function (node) {        return node.tagName.toLowerCase === 'div' ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;    }}// 也可以使用与acceptNode()方法类似的函数var filter = function (node) {        return node.tagName.toLowerCase() === 'div' ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;}

这里写图片描述
这里写图片描述

2、TreeWalker
比NodeIterator更加强大,提供了更多用于DOM遍历的方法,包括:previousNode()/ nextNode()/ parentNode()/ firstChild()/ lastChild()/ previousSibling()/ nextSibling(); 这使得TreeWalker可以沿任何方向遍历DOM结构;

创建相应实例可以使用document.createTreeWalker()方法,接收的参数与document.createNodeIterator()方法相同;filter其实还有一个常量参数NodeFilter.FILTER_REJECT,在NodeIterator中其与NodeFilter.FILTER_SKIP作用相同,都跳过某个特定节点;在TreeWalker中,NodeFilter.FILTER_REJECT会跳过相应节点及整个子树,NodeFilter.FILTER_SKIP只是跳过当前节点,会继续依次访问子树中的节点;
这里写图片描述

TreeWalker的currentNode属性返回的是任何遍历方法上次遍历中返回的节点;


范围

使用DOM2的范围接口可以在不受节点界限的限制下更方便的选择文档中的区域,便于对DOM实现更加精细的控制;

// 能力检测var supportRange = document.implementation.hasFeature('Range','2.0');var flag = typeof document.createRange === 'funciton';

创建范围实例可以使用无参方法document.createRang();以下是range实例的属性:
这里写图片描述

范围实例还有相应的方法selectNode()和selectNodeContents(),两者都接收一个DOM节点参数;

DOM范围复杂选择:setStart(referNode, offset) 和setEnd(referNode, offset),这些方法接收两个参数,第一个为参照节点,第二个为偏移量;另外有一个deleteContents()方法用于删除文档包含的内容;extractContents()与deleteContents()类似但是会返回移除的documentFragment。

range.collapse()用于折叠范围,参数为布尔值,true代表折叠到范围头部;检测折叠状态可以用于确定两个节点的相邻关系;

compareBoundaryPoints()比较两个DOM范围是否有公共边界,返回值为-1、0或1(第一范围的点位于第二范围的点之后)

range1.compareBoundaryPoints(Range.START_TO_START, range2);

range.cloneRange(),克隆DOM范围;

清理DOM范围:

range.detach()      // 从文档中分离range = null        // 解除引用
原创粉丝点击