DOM拓展

选择符API

querySelector()

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

//取得 body 元素
var body = document.querySelector("body"); 

//取得 ID 为"myDiv"的元素
var myDiv = document.querySelector("#myDiv"); 

//取得类为"selected"的第一个元素
var selected = document.querySelector(".selected"); 

//取得类为"button"的第一个图像元素
var img = document.body.querySelector("img.button"); 

querySelectorAll()

这个方法返回的是一个 NodeList 的实例。

//取得某<div>中的所有<em>元素(类似于 getElementsByTagName("em"))
var ems = document.getElementById("myDiv").querySelectorAll("em"); 

//取得class为"selected"的所有元素
var selecteds = document.querySelectorAll(".selected"); 

//取得所有<p>元素中的所有<strong>元素
var strongs = document.querySelectorAll("p strong"); 

matchesSelector()

为 Element 类型新增的一个方法

这个方法接收 一个参数,即 CSS 选择符

如果调用元素与该选择符匹配,返回 true;否则,返回 false

if (document.body.matchesSelector("body.page1")){ 
 //true 
} 

元素遍历

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

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

HTML5

与类相关的扩充

getElementsByClassName()接收一个参数:即一个包含一或多个类名的字符串,返回带有 指定类的所有元素的 NodeList。

//取得所有类中包含"username"和"current"的元素,类名的先后顺序无所谓
var allCurrentUsernames = document.getElementsByClassName("username current"); 

classList 属性

定义如下方法:

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

//添加"current"类
div.classList.add("current"); 

//切换"user"类
div.classList.toggle("user");

//确定元素中是否包含既定的类名
if (div.classList.contains("bd") && !div.classList.contains("disabled")){ 
 //执行操作
) 

//迭代类名
for (var i=0, len=div.classList.length; i < len; i++){ 
 doSomething(div.classList[i]); 
}

焦点管理

HTML5 也添加了辅助管理 DOM 焦点的功能。

document.activeElement 这个属性始终会引用 DOM 中当前获得了焦点的元素。

元素获得焦点的方式有页面加载、用户输入(通常是 通过按 Tab 键)和在代码中调用 focus()方法。

var button = document.getElementById("myButton"); 
button.focus(); 
alert(document.activeElement === button); //true 

document.hasFocus()用于确定文档是否获得了焦点。


HTMLDocument的变化

readyState 通过它来实现一个指示文档已经加载完成的指示器

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

  • loading,正在加载文档;
  • complete,已经加载完文档
//如果加载完成了 类似onload
if (document.readyState == "complete"){ 
 //执行操作
}

自定义数据属性

HTML5 规定可以为元素添加非标准的属性,但要添加前缀 data-,目的是为元素提供与渲染无关的 信息,或者提供语义信息。

可以通过元素的 dataset属性来访问自定义属性的值

//取得自定义属性的值
var appId = div.dataset.appId; 
var myName = div.dataset.myname;

//设置自定义值
div.dataset.appId = 23456; 
div.dataset.myname = "Michael";

插入标记

innerHTML

在读模式下,innerHTML 属性返回与调用元素的所有子节点(包括元素、注释和文本节点)对应 的 HTML 标记。

在写模式下,innerHTML 会根据指定的值创建新的 DOM 树,然后用这个 DOM 树完全 替换调用元素原先的所有子节点


outerHTML

在读模式下,outerHTML 返回调用它的元素及所有子节点的 HTML 标签。

在写模式下,outerHTML 会根据指定的 HTML 字符串创建新的 DOM 子树,然后用这个 DOM 子树完全替换调用元素


insertAdjacentHTML()

它接收两个参数:插入位置和要插入的 HTML 文本

第一个参数必须是下列值之一:

  • "beforebegin",在当前元素之前插入一个紧邻的同辈元素;
  • "afterbegin",在当前元素之下插入一个新的子元素或在第一个子元素之前再插入新的子元素;
  • "beforeend",在当前元素之下插入一个新的子元素或在最后一个子元素之后再插入新的子元素;
  • "afterend",在当前元素之后插入一个紧邻的同辈元素。
//作为前一个同辈元素插入
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>"); 

scrollIntoView()

通过滚动浏览器窗口或某个容器元素,调用 元素就可以出现在视口中

如果给这个方法传入 true 作为参数,或者不传入任何参数,那么窗口滚动 之后会让调用元素的顶部与视口顶部尽可能平齐。

如果传入 false 作为参数,调用元素会尽可能全部 出现在视口中

//让元素可见
document.forms[0].scrollIntoView();

拓展

children属性

children 属性与 childNodes 没有什么区别,即在元素只包含元素子节点时,这两个属性的值相同。

var childCount = element.children.length; 
var firstChild = element.children[0]; 

contains()方法

检测某个节点是不是另一个节点的后代

调用 contains()方法的应该是祖先节点,这个方法接收一个参数,即要检测的后代节点。

如果被检测的节点是后代节点, 该方法返回 true;否则,返回 false。

alert(document.documentElement.contains(document.body)); //true


插入文本

innerText

在通过 innerText 读取值时,它会按照由浅入深的顺序,将子文档树中的所有文本拼接起来。

在通过 innerText 写入值时,结果会删除元素的所有子节点,插入包含相应文本值的文本节点。

<div id="content"> 
 <p>This is a <strong>paragraph</strong> with a list following it.</p> 
 <ul> 
 <li>Item 1</li> 
 <li>Item 2</li> 
 <li>Item 3</li> 
 </ul> 
</div>

其 innerText 属性会返回下列字符串:

This is a paragraph with a list following it. 
Item 1 
Item 2 
Item 3

再设置内容后

div.innerText = "Hello world!";

页面的 HTML 代码就会变成如下所示,子节点全被移除了

<div id="content">Hello world!</div>


outerText

除了作用范围扩大到了包含调用它的节点之外,outerText 与 innerText 基本上没有多大区别。

多了的就是替代当前调用节点


滚动

下面列出 的几个方法都是对 HTMLElement 类型的扩展

  • scrollIntoViewIfNeeded(alignCenter):只在当前元素在视口中不可见的情况下,才滚 动浏览器窗口或容器元素,最终让它可见。如果当前元素在视口中可见,这个方法什么也不做。 如果将可选的 alignCenter 参数设置为 true,则表示尽量将元素显示在视口中部(垂直方向)。 Safari 和 Chrome 实现了这个方法。
  • scrollByLines(lineCount):将元素的内容滚动指定的行高,lineCount 值可以是正值, 也可以是负值。Safari 和 Chrome 实现了这个方法。
  • scrollByPages(pageCount):将元素的内容滚动指定的页面高度,具体高度由元素的高度决 定。Safari 和 Chrome 实现了这个方法。
//将页面主体滚动 5 行
document.body.scrollByLines(5); 

//在当前元素不可见的时候,让它进入浏览器的视口
document.images[0].scrollIntoViewIfNeeded(); 

//将页面主体往回滚动 1 页
document.body.scrollByPages(-1);