DOM扩展:DOM API的进一步增强[总结篇-下]

本文承接《DOM扩展:DOM API的进一步增强[总结篇-上],继续总结DOM扩展相关的功能和API。

3.6 插入标记

DOM1级中的接口已经提供了向文档中插入内容的接口,但是在给文档插入大量HTML标记的时候操作还是很繁杂的,每次插入一个元素,不仅要调用创建元素和文本节点的接口,还要调用appendChild等向文档中添加元素的接口,而且在添加时还要按照正确的顺序。而如果使用插入标记的方法,直接向文档中插入HTML字符串,由执行环境自动解析HTML字符串并创建相应的节点并添加到文档中,这样的话操作就方便多了。与插入标记相关的DOM扩展总结如下:

3.6.1 innerHTML属性

使用innerHTML可以读取元素所有子节点对应的HTML字符串(包括元素、注释节点和文本);也可以为元素设置子节点的HTML标记,此时会根据指定的值创建新的DOM树,然后用新的DOM树替换元素的子节点。

(1)读取innerHTML属性

以下面的代码为例:

<div id="wrapper">    <p>一个段落在这里</p>    <span>这里是一个span</span></div>

我们如果获取div#wrapper的innerHTML值应该就是:
<p>一个段落在这里</p><span>这里是一个span</span>

但是IE8及以下的浏览器,在使用innerHTML属性时返回的字符串有两处不同:

[1]所有的标签都会转为大写

[2]所有的空白节点都会被去掉

仍以上面的代码为了,在IE8及以下的浏览器中返回的内容就是:

<P>一个段落在这里</P><SPAN>这里是一个span</SPAN>

(2)设置innerHTML属性

设置innerHTML属性时,HTML字符串会被解析为DOM树并替换元素的所有子节点。如果传入的字符串不包含任何标签,那么生成的就是文本节点,而如果传入的字符串包含由HTML标签,那么标签就会被解析为相应的HTML元素,这一点与创建Text类型节点时的情况是大不相同的:

我们还是以上面的div#wrapper为例:

如果调用:

div.innerHTML = "<strong>\"This is innerHTML\"</strong>";

则<strong>会被正确地解析,其中的文本就会被渲染成粗体。

使用innerHTML也存在一些限制:

[1]script标签

在大部分浏览器中,通过innerHTML插入的<script>标签不会被执行,只有IE9及以下的浏览器会执行,但也需要满足一定的条件,首先需要为script添加defer特性,其次<script>标签必须位于"有作用域"的元素之后("有作用域"的元素这里可以理解为会直观显示在页面上的元素,比如script,style这些元素是不会显示在页面上的,而input、div等元素会直接显示在页面上,因此可以称为"有作用域")。还是以上面的div#wrapper为例,有如下代码:

div.innerHTML = "<script>alert(‘dd‘)<\/script>";

代码执行后,标签会被插入div中,但脚本在任何浏览器中都不会执行。再来修改一下代码:

div.innerHTML = "<script defer=‘defer‘>alert(‘dd‘)<\/script>";

这段代码为innerHTML加入了一个defer特性,但正如上文所讲的,script是一个"没有作用域"的元素,所以在IE9及以下浏览器中,脚本还是不会被执行。这个时候只要在<script>前面添加一个字符串或者其他"有作用域"的元素即可,为了不影响文档的实际内容,一般在script标签之前添加一个隐藏的input元素即可,代码如下:

div.innerHTML = "<input type=‘hidden‘/><script defer=‘defer‘>alert(‘dd‘)<\/script>";

这样在IE9及以下的浏览器中,脚本就能够执行了。

注:如果是引入外部javascript文件,那么所有浏览器都不会下载执行js文件和其中的代码

[2]style和link标签

在IE8及以下的浏览器中,如果插入style标签,必须也要跟随在一个"有作用域"的元素之后,因此可以采用<script>一节中介绍的方法。高版本IE及其他浏览器中插入的style样式都可以被执行。

另外,如果使用link标签引入外部样式,那么和style标签的效果是一样的

还有一些元素是不支持innerHTML属性的,包括:<table>、 <thead>、 <tbody>、 <tfoot>、 <tr>、 <style>、 <html>、 <head>、 <frameset>、<col>、<colgroup>

由于innerHTML可以插入HTML标签,那么就涉及到安全问题,最典型的的就是XSS,因此在使用innerHTML时应该对插入的字符串进行安全处理,特别是需要保存到数据库中的字符串代码。比如插入的字符串不应该包含脚本代码(及时在一些浏览器中脚本代码不会执行),不应该包含事件处理程序和外部链接等。IE8中提供了window.toStaticHTML(),可以将传入的字符串进行处理:删除脚本节点和事件处理程序。

3.6.2 outerHTML属性

从字面上

,outerHTML与innerHTML的不同就在于"outer",也就是说,outerHTML属性在读取或写入时除了包含所有子节点,同时也把自己算进去了。我们还是以3.6.1中的div#wrapper为例,读取outerHTML时返回的是:

<div id="wrapper">    <p>一个段落在这里</p>    <span>这里是一个span</span></div>

在IE8及以下的浏览器返回:

<DIV id=wrapper><P>一个段落在这里</P><SPAN>这里是一个span</SPAN></DIV>

而如果是写入outerHTML属性的话,则会将div本身直接替换掉,这也是与innerHTML的不同之处。

3.6.3 insertAdjacentHTML方法

insertAdjacentHTML方法为元素提供了更加灵活的标记插入方法,它接收两个参数:插入的位置和HTML字符串,其中插入的位置必须是下面几个参数:

"beforebegin":在元素之前插入一个紧邻的同辈元素

"afterbegin":如果元素没有子元素,那么就直接插入;如果元素有子元素,就在第一个子元素之前插入

"beforeend":如果元素没有子元素,那么就直接插入;如果元素有子元素,就在最后一个子元素之后插入

"afterend":在元素之后插入一个紧邻的同辈元素

我们仍以3.6.1中的div为例,调用如下代码:

div.insertAdjacentHTML("beforeend","<p>在结束前插入一个</p>");console.log(div.innerHTML);

则返回的代码就是:


<p>一个段落在这里</p><span>这里是一个span</span><p>在结束前插入一个</p>

insertAdjacentHTML方法的兼容性如下图:


在IE6-8下,table, tbody, thead,  tr 元素调用这个方法会报错。

3.6 scrollIntoView()方法

DOM1级中的接口已经scrollIntoView方法可以在所有的HTML元素上调用,调用这个方法后,浏览器会通过滚动窗口或者某个容器窗口来让元素出现在视口中。

这个方法接收一个布尔型参数,默认为true,如果为true的话,滚动后浏览器会让视口顶部与元素顶部尽可能平齐;如果为false,调用元素会尽可能出现在视口中。

4

专有扩展

 

不同的浏览器开发商可能会为DOM扩展不同的功能,这些功能有的被吸收进入了标准,正如第3章中所介绍的这些扩展,而有的功能却还没有被纳入标准中,不过这并不代表着这些功能以后也不会被写入标准中,只是目前这些功能还是各浏览器专有的扩展,只能在特定的浏览器中使用。

4.1 文档模式

IE8中引入了文档模式的概念,文档模式决定了我们可以使用哪些功能,也就是说,文档模式决定了我们可以使用哪个级别的CSS,可以使用JavaScript API中的哪些功能以及如何对待文档类型。之后的IE版本都提供了向下兼容的文档模式,比如在IE9中,可选的文档模式有:IE5(以混杂模式渲染页面)、IE7(以IE7的标准模式渲染页面)、IE8(以IE8的标准模式渲染页面,到了IE8,DOM Selectors API、CSS2.1的完整功能以部分CSS3的功能就都可以使用了)、IE9(以IE9的标准模式渲染页面,到了IE9,ES5、CSS3以及更多的HTML5的功能也都可以使用了)

要强制浏览器以某种模式渲染页面,可以通过设置HTTP的X-UA-Compatible头部或设置对应的meta标签来实现,声明方式为:

<meta http-equiv="x-ua-compatible" content="IE=IEVersion"/>

其中,IEVersion的可能取值有:

[1]edge:始终以最新的文档模式来渲染页面,忽略文档类型声明

[2]EmulateIEXX:XX代表某个IE版本,即如果有文档类型声明,那么就以XX版本的IE标准模式来渲染页面,否则把文档模式设为IE5

[3]XX:XX代表某个IE版本,即忽略文档类型声明,以XX版本的IE标准模式渲染页面

如果没有设置X-UA-Compatible,则浏览器会根据文档类型声明选择最佳的文档模式进行渲染。

document.documentMode可以判断文档当前所处的文档模式,这个属性只有IE支持。

4.2 children属性

IE8及以下的浏览器在处理文本节点的空白节点时与其他浏览器有所不同,因此使用childNodes属性遍历DOM树时还需要判断某个子节点的具体类型,而children属性的出现可以解决这个问题,它只返回一个元素所有的子元素。

注:IE8及以下的浏览器也会返回注释节点。

IE5+,Firefox3.5+,chrome,Opera8+,Safari3+支持children属性。

4.3 contains方法

实际开发中,经常需要判断一个节点是否包含另一个节点,比如我们有如下HTML代码:

<body>
<div id="div-1">
    <div id="title">
        <h1 id="title-h1">标题</h1>
        <span id="more">更多</span>
    </div>
</div>
<div id="div-2">
    <div id="content-wrapper">
        <div id="block">
            <p id="desc">这里是一段描述</p>
            <img id="img" src=""/>
        </div>
    </div>
</div>
</body>

  

如果我们想要判断div#div-2是否包含span#more,如果只借助DOM1级的API,那么我们会可能写出如下代码:

var div2 = document.getElementById("div-2"),
div1 = document.getElementById("div-1"),
more = document.getElementById("more");
alert(nodeContains(div1, more));
alert(nodeContains(div2, more));
function nodeContains(node, childNode){
var result = false;
while(childNode != null){
if(childNode === node){
result = true;
break;
        }
        childNode = childNode.parentNode;
    }
return result;
}

代码执行后将分别弹出true和false

注:Firefox9+和其他浏览器都支持contains方法。

有了contains方法之后,我们可以直接使用:

alert(div1.contains(more));
alert(div2.contains(more));

也将分别弹出true和false。

另外,DOM3级中又定义了compareDocumentPosition方法,也可以用来判断一个节点是否包含另一个节点,这里我们不再详解这个方法,可以参考:

http://www.w3.org/TR/domcore/#dom-node-comparedocumentposition

4.4 插入文本

3.6节介绍了插入标记相关的属性:innerHTML和outerHTML,并且这两个特性已经被纳入了HTML5标准之中,而另外两个插入文本相关的属性则没有被标准看上,它们就是innerText和outerText。

4.4.1 innerText属性

使用innerText属性可以读取元素内的文本内容,也可以设置元素的文本内容,

(1)读取innerText属性

如果调用Element.innerText属性,会按照由浅到深的顺序,将元素的所有文本节点拼接起来并返回。但是由于不同的浏览器处理空白符的方式不同,因此返回的字符串也可能不包含原始HTML代码中的缩进。有如下代码:

<div id="wrapper"><p>一个段落在这里</p><span>这里是一个span</span></div>

那么调用div#wrapper的innerText属性返回的内容可能是:

一个段落在这里

这里是一个span

也可能是:

一个段落在这里这里是一个span

这主要还是由于不同浏览器处理空白符节点的方式不同而导致的。

(2)设置innerText属性

如果为一个元素设置innerText属性,则意味着删除元素的所有子节点,并将文本节点插入,文本中包含的HTML语法字符都会被转义,还是以上面的div#wrapper为例:

div.innerText = "<strong>Hello</strong>";

代码执行后,显示结果为:

支持innerText属性的浏览器有:IE4+,chrome,Opera8+,Safari3+;特别注意的是:firefox不支持innerHTML,但是有一个类似的textContent属性,另外还支持textContent属性的有:IE9+,chrome,Opera10+,Safari3+

注:textContent和innerText返回的内容有时候是不相同,比如innerText会忽略元素内部所有的脚本标签代码和样式标签代码,但textContent却不会忽略。

4.4.2 outerText属性

与innerText属性相似,在读取时,返回的结果与innerText相同,在设置时,则会将整个节点直接替换掉。

时间: 2024-10-12 14:24:33

DOM扩展:DOM API的进一步增强[总结篇-下]的相关文章

DOM扩展-Selectors API(选择符 API)

DOM扩展 对DOM的两个主要扩展是SelectorsAPI(选择符API)和HTML5 SelectorsAPI(选择符API)是由W3C发起制定的一个标准,致力于浏览器原生支持CSS查询,SelectorsAPILevel 1的核心是两个方法:querySelector()和querySelectorAll(),可以通过Document及Element类型的实例调用他们. querySelector()方法接受一个CSS选择符,返回与该模式匹配的第一个元素,如果没有找到匹配的元素,返回nul

javascript高级程序设计 第十一章--DOM扩展

javascript高级程序设计 第十一章--DOM扩展DOM最主要的扩展就是选择符API.HTML5和Element Traversal Selectors API:定义了两个方法 querySelector() 和 querySelectorAll(),能够基于CSS选择符从DOM中取得元素.querySelector()方法接收一个CSS选择符,返回该模式匹配的第一个元素,querySelectorAll()接收的参数一样,但是返回NodeList实例: matchesSelector()

js DOM 扩展

1. 选择符API querySelector()          返回匹配的第一个元素,接收一个 CSS 选择符.没有找到返回 null. querySelectorAll()      返回所有匹配的一个 NodeList, 这是一个快照不会动态改变.接收一个 CSS 选择符. mathesSelecttor()      如果调用元素与该选择符匹配,返回true, 否则返回 false. 接收一个 CSS 选择符. 2. 与类相关的扩充 getElementsByClassName()

JavaScript学习 八、DOM扩展

对DOM的两个主要扩展是Selectors API(选择符API)和HTML5.这两个扩展都是源自开发社区.此外还有一个不那么因为瞩目的ELement Traversal(元素遍历)规范.为DOM添加了一些属性. 选择符API 众多JavaScript 库中最常用的一项功能,就是根据CSS选择符选择与某个模式匹配的DOM元素. 实际上 jQuery 的核心就是通过CSS选择符查询DOM 文档取得元素的引用,从而抛开了 getElementById() 和 getElementsByTagName

DOM扩展学习笔记

对DOM的两个主要扩展是Selectors API(选择符API)和HTML5,还有一个不太瞩目的Element Traversal元素遍历规范为DOM添加了一些属性,另外还有一些专有扩展. 选择符API 元素遍历 HTML5 专有扩展 选择符API 让浏览器原生支持css查询,原理就是所有实现这一功能的JavaScript库都会写一个基础的CSS解析器,然后再使用已有的DOM方法查询文档并找到匹配的节点.当把这个功能变成原生API后,解析和树查询操作可以在浏览器内部通过编译后的代码来完成,极大

JavaScript的DOM扩展

虽然 DOM 为与 XML 及 HTML 文档交互制定了一系列核心 API,但仍然有几个规范对标准的 DOM进行了扩展.这些扩展中有很多原来是浏览器专有的,但后来成为了事实标准,于是其他浏览器也都提供了相同的实现.本章介绍的三个这方面的规范如下. 1 Selectors API,定义了两个方法,让开发人员能够基于 CSS 选择符从 DOM中取得元素,这两个方法是 querySelector() 和 querySelectorAll() . 2 Element Traversal,为 DOM 元素

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

1. DOM扩展 1.1 选择符API l querySelector() 接收一个css选择符,返回与该模式匹配的第一个元素 l querySelectorAll() 接收一个css选择符,返回所有匹配的NodeList元素 1.2 HTML5 1.2.1 与类相关的扩充 l getElementsByClassName() 接收一个参数,一个包含一或者多个类名的字符串,返回带有指定类的所有元素的NodeList l classList属性,add(value),contains(value)

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

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

读书笔记 - js高级程序设计 - 第十一章 DOM扩展

对DOM的两个主要的扩展 Selectors API HTML5 Element Traversal 元素遍历规范 querySelector var body = document.querySelector("body"); var myDiv = document.querySelector("#myDiv"); 取得id为myDiv的元素 var selected = document.querySelector(".selected")