第11章DOM扩展
对DOM 的两个主要的扩展是Selectors API(选择符API)和HTML5。这两个扩展都源自开发社区,而将某些常见做法及API 标准化一直是众望所归。此外,还有一个不那么引人瞩目的Element Traversal(元素遍历)规范,为DOM添加了一些属性。虽然前述两个主要规范(特别是HTML5)已经涵盖了大量的DOM 扩展,但专有扩展依然存在。本章也会介绍专有的DOM扩展。
- 理解Selectors API
- 使用HTML5 DOM扩展
- 了解专有的DOM扩展
理解Selectors API
querySelector()
querySelector()方法接收一个CSS 选择符,返回与该模式匹配的第一个元素,如果没有找到匹配的元素,返回null。
css选择符有三种
- 标签(元素)选择符
- ID选择符
- 类选择符
<div class="A" id="a">querySelector</div>
<div class="B" id="a">querySelector</div>
<script>
//类选择符
var A=document.querySelector(".A");
alert(A.className=="A");//true
//标签选择符
var a=document.querySelector("div");
alert(a.className);//A
//ID选择符
var A=document.querySelector("#a");
alert(A.className);//A
</script>
querySelectorAll()
querySelectorAll()方法接收的参数与querySelector()方法一样,都是一个CSS 选择符,但返回的是所有匹配的元素而不仅仅是一个元素。这个方法返回的是一NodeList 的实例。要取得返回的NodeList 中的每一个元素,可以使用item()方法,也可以使用方括号语法。
NodeList[i]
NodeList.item(i)
<div class="A">querySelectorAll 1</div>
<div class="A">querySelectorAll 2</div>
<script>
var classNames=document.querySelectorAll(".A");
for(var i=0,len=classNames.length;i<len;i++)
{
alert(classNames[i].innerHTML);
//querySelectorAll 1
//querySelectorAll 2
}
</script>
matchesSelector()
这个方法接收一个参数,即CSS 选择符,如果调用元素与该选择符匹配,返回true;否则,返回false.
<div class="A"></div>
<script>
var A=document.querySelector(".A");
alert(A.webkitMatchesSelector(".A"));//true
</script>
元素遍历
对于元素间的空格,IE9 及之前版本不会返回文本节点,而其他所有浏览器都会返回文本节点。这样,就导致了在使用childNodes 和firstChild 等属性时的行为不一致,为了弥补这一差异,而同时又保持DOM规范不变,Element Traversal 规范(www.w3.org/TR/ElementTraversal/)新定义了一组属性.
下面的属性都不会包括标签之间的文本节点
- childElementCount:返回子元素(不包括文本节点和注释)的个数。
- firstElementChild:指向第一个子元素。
- lastElementChild:指向最后一个子元素。
- previousElementSibling:指向前一个同辈元素。
- nextElementSibing:指向后一个同辈元素。
<ul>
<li>OnePlus 5</li>
<li>OnePlus 5T</li>
<li>OnePlus 6</li>
</ul>
<script>
var first=document.querySelector("ul").firstElementChild;
alert(first.innerHTML);//OnePlus 5
var last=document.querySelector("ul").lastElementChild;
alert(last.innerHTML);//OnePlus 6
alert(last.previousElementSibling.innerHTML);//OnePlus 5T
</script>
HTML5
与类相关的扩充1.getElementsByClassName()方法
getElementsByClassName()方法接收一个参数,即一个包含一或多个类名的字串,返回带有指定类的所有元素的NodeList。
注意:因为getElementsByClassName是动态更新的属性方法,一旦更改了元素中的类名,原先获取到的对象就会失效
<div class="A B C">A B C</div>
<script>
var div=document.getElementsByClassName("A B C");
console.log(div[0].classList.length);//3
div[0].classList.remove("B");//删除了B
console.log(div[0].className);//报错了,因为类名已经更新,原有的div对象已失效
console.log(document.querySelector("div").className);//A C
</script>
2. classList 属性
顾名思义就是类的目录和集合。返回一个元素的类属性的实时DOMTokenList集合.
HTML5 新增了一种操作类名的方式,可以让操作更简单也更安全,那就是为所有元素添加classList 属性。有一个表示自己包含多少元素的length 属性,而要取得每个元素可以使用item()方法,也可以使用方括号语法。
classList属性有如下方法
- add(value):将给定的字符串值添加到列表中。如果值已经存在,就不添加了。
- contains(value):表示列表中是否存在给定的值,如果存在则返回true,否则返回false。
- remove(value):从列表中删除给定的字符串。
- toggle(value):如果列表中已经存在给定的值,删除它;如果列表中没有给定的值,添加它。
<div class="A B C">ABC</div>
<script>
var div=document.querySelector(".A");
console.log(div.classList[0]);//A
console.log(div.classList[1]);//B
div.classList.add("D");
console.log(div.className);//A B C D
</script>
3.插入标记 innerHTML 属性
读模式:属性返回的是调用元素的所有子节点(包括元素、注释和文本节点)对应
的HTML 标记。
写模式:innerHTML属性会根据指定的值创建新的DOM树,然后用这棵DOM树完全代替调用原先的所有子节点。(可以插入元素标签和<style>样式标签)。
并不是所有元素都支持innerHTML 属性。不支持innerHTML 的元素有:<col><colgroup>、<frameset>、<head>、<html>、<style>、<table>、<tbody>、<thead>、<tfoot>和<tr>
<div>
<p>p段落</p>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</div>
<script>
console.log(document.querySelector("div").innerHTML);
</script>
结果返回的是下面的标签
<p>p段落</p>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
4.插入标记 outerHTML 属性
该属性与innerHTML属性类似,只不过调用元素调用时在读和写模式时也包含自身的元素。
<div>
<p>p段落</p>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</div>
<script>
console.log(document.querySelector("div").outerHTML);
</script>
结果返回的是下面的标签
<div>
<p>p段落</p>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul>
</div>
5.insertAdjacentHTML()方法
插入标记的最后一个新增方式是insertAdjacentHTML()方法。这个方法最早也是在IE 中出现的,它接收两个参数:插入位置和要插入的HTML 文本。第一个参数必须是下列值之一:
- "beforebegin",在当前元素之前插入一个紧邻的同辈元素;
- "afterbegin",在当前元素之下插入一个新的子元素或在第一个子元素之前再插入新的子元素;
- "beforeend",在当前元素之下插入一个新的子元素或在最后一个子元素之后再插入新的子元素;
- "afterend",在当前元素之后插入一个紧邻的同辈元素。
注意,这些值都必须是小写形式。第二个参数是一个HTML 字符串(
//作为前一个同辈元素插入
element.insertAdjacentHTML("beforebegin", "<p>Hello world!</p>");
//作为第一个子元素插入
element.insertAdjacentHTML("afterbegin", "<p>Hello world!</p>");
//作为最后一个子元素插入
element.insertAdjacentHTML("beforeend", "<p>Hello world!</p>");
//作为后一个同辈元素插入
element.insertAdjacentHTML("afterend", "<p>Hello world!</p>");
专有模式
children属性
只包含元素中同样还是元素的子节点除此之外,children 属性与childNodes 没有什么区别,即在元素只包含元素子节点时,这两个属性的值相同。
contains()方法
在实际开发中,经常需要知道某个节点是不是另一个节点的后代。
用父元素调用contains()方法,这个方法接收一个参数,即要检测的后代节点。。如果被检测的节点是后代节点,该方法返回true;否则,返回false
/*双逻辑非(!!)操作符
作用:双逻辑非操作会把一个值(数字,字符串...)转化为布尔值。第一次逻辑非是取反,第二次逻辑非是取值对应的布尔值
优点:双逻辑非操作符提高了程序执行的效率,比先存储后访问的效果更好*/
/*隐士转换布尔类型
* var a=Boolean(3);//true等同于!!3
alert(a);*/
/*
contains()方法
作用:判断调用元素的后代节点是否包含传入的参数节点,包含返回true不包含返回false
compareDocumentPosition()方法
*/
alert(document.documentElement.contains(document.body));//查看HTML元素是否包含body节点
alert(!!2);//true
alert(document.documentElement.contains(document.body)); //true
innerText属性和outerText属性(不常用)
读取:由浅入深把子文档树中的所有文本拼接起来。
写入:删除所有子节点,插入包含文本值的文本节点(元素标签会被解析成字符串)。
注意:由于不同浏览器处理空白符的方式不同,因此输出的文本可能会也可能不会包含原始HTML 代码中的缩进。