《Javascript 高级程序设计(第三版)》笔记0x12 DOM扩展

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/funkstill/article/details/85018491

目录

选择符 API

    querySelector()方法

     querySelectorAll()方法

     matchesSelector()方法

元素遍历

 HTML5

    与类相关的扩充

        getElementsByClassName()方法

        classList 属性

    焦点管理

    HTMLDocument的变化

        readyState 属性

        兼容模式

        head 属性

    字符集属性

    自定义数据属性

    插入标记

        innerHTML 属性

        outerHTML 属性

        内存与性能问题

     scrollIntoView()方法

 专有扩展

    文档模式

    children属性 

     contains()方法

        compareDocumentPosition()

     插入文本

         innerText 属性

         outerText 属性

     滚动


选择符 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");
//取得类为"selected"的所有元素
var selecteds = document.querySelectorAll(".selected");
//取得所有<p>元素中的所有<strong>元素
var strongs = document.querySelectorAll("p strong");

var i, len, strong;
for (i=0, len=strongs.length; i < len; i++){
	strong = strongs[i]; //或者 strongs.item(i)
	strong.className = "important";
}

     matchesSelector()方法

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

function matchesSelector(element, selector){
	if (element.matchesSelector){
		return element.matchesSelector(selector);
	} else if (element.msMatchesSelector){
		return element.msMatchesSelector(selector);
	} else if (element.mozMatchesSelector){
		return element.mozMatchesSelector(selector);
	} else if (element.webkitMatchesSelector){
		return element.webkitMatchesSelector(selector);
	} else {
		throw new Error("Not supported.");
	}
}
if (matchesSelector(document.body, "body.page1")){
	//执行操作
}

元素遍历

     对于元素间的空格, IE9 及之前版本不会返回文本节点,而其他所有浏览器都会返回文本节点。这样,就导致了在使用 childNodes 和 firstChild 等属性时的行为不一致。为了弥补这一差异,而同时又保持 DOM 规范不变, Element Traversal 规范(www.w3.org/TR/ElementTraversal/)新定义了一组属性。
    Element Traversal API 为 DOM 元素添加了以下 5 个属性。
        childElementCount:返回子元素(不包括文本节点和注释)的个数。
        firstElementChild:指向第一个子元素; firstChild 的元素版。
        lastElementChild:指向最后一个子元素; lastChild 的元素版。
        previousElementSibling:指向前一个同辈元素; previousSibling 的元素版。
        nextElementSibling:指向后一个同辈元素; nextSibling 的元素版。

var i,
len,
child = element.firstElementChild;
while(child != element.lastElementChild){
	processChild(child); //已知其是元素
	child = child.nextElementSibling;
}

 HTML5

    与类相关的扩充

        getElementsByClassName()方法

//返回带有指定类的所有元素的 NodeList。
//取得所有类中包含"username"和"current"的元素,类名的先后顺序无所谓
var allCurrentUsernames = document.getElementsByClassName("username current");
//取得 ID 为"myDiv"的元素中带有类名"selected"的所有元素
var selected = document.getElementById("myDiv").getElementsByClassName("selected");

        classList 属性

//删除"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]);
}

    焦点管理

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

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

    HTMLDocument的变化

        readyState 属性

if (document.readyState == "complete"){// loading和complete
  //执行操作
}

        兼容模式

if (document.compatMode == "CSS1Compat"){
	alert("Standards mode");
} else {
	alert("Quirks mode");
}

        head 属性

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

    字符集属性

alert(document.charset); //"UTF-16"
document.charset = "UTF-8";

if (document.charset != document.defaultCharset){
	alert("Custom character set being used.");
}

    自定义数据属性

<!--为元素添加非标准的属性,但要添加前缀 data-,目的是为元素提供与渲染无关的
信息,或者提供语义信息。这些属性可以任意添加、随便命名,只要以 data-开头即可。-->
<div id="myDiv" data-appId="12345" data-myname="Nicholas"></div>

    插入标记

        innerHTML 属性

        在读模式下, innerHTML 属性返回与调用元素的所有子节点(包括元素、注释和文本节点)对应的 HTML 标记。在写模式下, innerHTML 会根据指定的值创建新的 DOM 树,然后用这个 DOM 树完全替换调用元素原先的所有子节点。

        outerHTML 属性

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

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

//注意小写
//作为前一个同辈元素插入
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>");

        内存与性能问题

        在使用 innerHTML、outerHTML 属性和 insertAdjacentHTML()方法时,最好先手工删除要被替换的元素的所有事件处理程序和 JavaScript 对象属性。

//最好的做法是单独构建字符串,然后再一次性地将结果字符串赋值给 innerHTML
var itemsHtml = "";
for (var i=0, len=values.length; i < len; i++){
	itemsHtml += "<li>" + values[i] + "</li>";
}
ul.innerHTML = itemsHtml;

     scrollIntoView()方法

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

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

 专有扩展

    文档模式

        IE8 引入了一个新的概念叫“文档模式”(document mode)。页面的文档模式决定了可以使用什么功能。换句话说,文档模式决定了你可以使用哪个级别的 CSS,可以在 JavaScript 中使用哪些 API,以及如何对待文档类型(doctype)。

    children属性 

        这个属性是 HTMLCollection 的实例,只包含元素中同样还是元素的子节点。除此之外,children 属性与 childNodes 没有什么区别,即在元素只包含元素子节点时,这两个属性的值相同。

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

     contains()方法

alert(document.documentElement.contains(document.body)); //true
//测试了<body>元素是不是<html>元素的后代,在格式正确的 HTML 页面中,以上代码返回 true。

        compareDocumentPosition()

        为模仿 contains()方法,应该关注的是掩码 16。可以对 compareDocumentPosition()的结果执行按位与,以确定参考节点(调用 compareDocumentPosition()方法的当前节点)是否包含给定的节点(传入的节点)。 

var result = document.documentElement.compareDocumentPosition(document.body);
alert(!!(result & 16));//20,表示“居后”的 4 加上表示“被包含”的 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;
	}
}

     插入文本

         innerText 属性

        通过 innertText 属性可以操作元素中包含的所有文本内容,包括子文档树中的文本。在通过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>
<!--div返回值
This is a paragraph with a list following it.
Item 1
Item 2
Item 3
-->

        支持 innerText 属性的浏览器包括 IE4+、 Safari 3+、 Opera 8+和 Chrome。 Firefox 虽然不支持innerText,但支持作用类似的 textContent 属性。 textContent 是 DOM Level 3 规定的一个属性,其他支持 textContent 属性的浏览器还有 IE9+、 Safari 3+、 Opera 10+和 Chrome。为了确保跨浏览器兼容,有必要编写一个类似于下面的函数来检测可以使用哪个属性。

function getInnerText(element){
	return (typeof element.textContent == "string") ?
	element.textContent : element.innerText;
}
function setInnerText(element, text){
	if (typeof element.textContent == "string"){
		element.textContent = text;
	} else {
		element.innerText = text;
	}
}

         outerText 属性

        除了作用范围扩大到了包含调用它的节点之外, outerText 与 innerText 基本上没有多大区别。在读取文本值时, outerText 与 innerText 的结果完全一样。但在写模式下, outerText 就完全不同了: outerText 不只是替换调用它的元素的子节点,而是会替换整个元素(包括子节点)。

div.outerText = "Hello world!";
//相当于,新的文本节点会完全取代调用 outerText 的元素。此后,该元素就从文档中被删除,无法访问
var text = document.createTextNode("Hello world!");
div.parentNode.replaceChild(text, div);

     滚动

//将页面主体滚动 5 行
document.body.scrollByLines(5);
//在当前元素不可见的时候,让它进入浏览器的视口
document.images[0].scrollIntoViewIfNeeded();
//将页面主体往回滚动 1 页
document.body.scrollByPages(-1);

猜你喜欢

转载自blog.csdn.net/funkstill/article/details/85018491