本文共--字 阅读约--分钟 | 浏览: -- Last Updated: 2021-12-15
虽然DOM
为与XML
及HTML
文档交互制定了一系列核心API
,但仍然有几个规范对标准的DOM
进行了扩展。这些扩展中有很多原来是浏览器专有的,但后来成为了事实标准,于是其他浏览器也都提供了相同的实现。
接收一个CSS
选择符(字符串),返回与该模式匹配的第一个元素,如果没有找到匹配的元素,返回null
。
通过Document
类型调用querySelector
方法时,会在文档元素的范围内查找匹配的元素。而通过Element
类型调用,只会在该元素后代元素的范围内查找匹配的元素。如果传入了不被支持的选择符,会抛出错误。
接收的参数与querySelector
方法一样,都是一个CSS
选择符,但返回的是所有匹配的元素而不仅仅是一个元素。返回的值实际上是带有所有属性和方法的NodeList
。如果没有找到匹配的元素,NodeList
就是空的。如果传入了不被支持的选择符,会抛出错误。
childElementCount
:返回子元素的个数(不包括文本节点和注释)。firstElementChild
:指向第一个子元素;firstChild
的元素版。lastElementChild
:指向最后一个子元素;lastChild
的元素版。previousElementSibling
:指向前一个同辈元素;previousSibling
的元素版。nextElementSibling
:指向后一个同辈元素;nextSibling
的元素版。在操作类名时,需要通过className
属性添加、删除和替换类名。因为className
中是一个字符串,所以即使只修改字符串一部分,也必须每次都设置整个字符串的值。
因此,HTML5
为所有元素添加了classList
属性。这个classList
属性是新集合类型DOMTokenList
的实例。与其他DOM
集合类似,DOMTokenList
有一个表示己包含多少元素的length
属性,而要取得每个元素可以使用item()
方法,也可以使用方括号语法。此外,这个新类型还定义如下方法。
add(value)
:将给定的字符串值添加到列表中。如果值已经存在,就不添加了。contains(value)
:表示列表中是否存在给定的值,如果存在则返回true
,否则返回false
。remove(value)
:从列表中删除给定的字符串。toggle(value)
:如果列表中已经存在给定的值,删除它;如果列表中没有给定的值,添加它。HTML5
也添加了辅助管理DOM
焦点的功能。首先就是document.activeElement
属性,这个属性始终会引用DOM
中当前获得了焦点的元素。元素获得焦点的方式有页面加载、用户输入(通常是通过按Tab
键)和在代码中调用focus()
方法。
默认情况下,文档刚刚加载完成时,document.activeElement
中保存的是document.body
元素的引用。文档加载期间,document.activeElement
的值为null
。
另外就是新增了document.hasFocus()
方法,这个方法用于确定文档(页面)是否获得了焦点。通过检测文档是否获得了焦点,可以知道用户是不是正在与页面交互。
var button = document.getElementById("myButton");
button.focus();
alert(document.hasFocus()); //true
1、readyState
属性
Document
的readyState
属性有两个可能的值:
"loading"
,正在加载文档;"complete"
,已经加载完文档。使用document.readyState
的最恰当方式,就是通过它来实现一个指示文档已经加载完成的指示器。在这个属性得到广泛支持之前,要实现这样一个指示器,必须借助onload
事件处理程序设置一个标签,表明文档已经加载完毕。
if (document.readyState == "complete"){
//文档已经加载完成 执行操作
}
2、兼容模式
自从IE6 开始区分渲染页面的模式是标准的还是混杂的,检测页面的兼容模式就成为浏览器的必要功能。IE 为此给document
添加了一个名为compatMode
的属性,这个属性就是为了告诉开发人员浏览器采用了哪种渲染模式。在标准模式下,document.compatMode
的值等于"CSS1Compat"
,而在混杂模式下,document.compatMode
的值等于"BackCompat"
。
3、head 属性
HTML5
新增了document.head
属性,引用文档的<head>
元素。要引用文档的<head>
元素,可以结合使用这个属性和另一种后备方法。
var head = document.head || document.getElementsByTagName("head")[0];
// 实现document.head 属性的浏览器包括Chrome 和Safari 5。
4、charset 字符集属性
HTML5
新增了几个与文档字符集有关的属性。其中,charset
属性表示文档中实际使用的字符集,也可以用来指定新字符集。默认情况下,这个属性的值为"UTF-16"
,但可以通过<meta>
元素、响应头部或直接设置charset
属性修改这个值。
alert(document.charset); //"UTF-16"
document.charset = "UTF-8";
5、自定义数据属性
HTML5
规定可以为元素添加非标准的属性,但要添加前缀data-
,目的是为元素提供与渲染无关的信息,或者提供语义信息。这些属性可以任意添加、随便命名,只要以data-
开头即可。
添加了自定义属性之后,可以通过元素的dataset
属性来访问自定义属性的值。dataset
属性的值是DOMStringMap
的一个实例,也就是一个名值对儿的映射。在这个映射中,每个data-name
形式的属性都会有一个对应的属性,只不过属性名没有data-
前缀(比如,自定义属性是data-myname
,那映射中对应的属性就是myname
)。
需要注意的是,所有的data-
后面的 key 值,所有的驼峰写法会被转换为连续的小写,所有的-线分隔会被转换成驼峰写法。
<div id="myDiv" data-appId="12345" data-my-name="Nicholas"></div>
<script>
var div = document.getElementById("myDiv");
//取得自定义属性的值
var appId = div.dataset.appId;
console.log(appId); // 取不到值 undefined
var appId = div.dataset.appid; // 大写都会被转变为小写
console.log(appId); // 12345
var myName = div.dataset.myName; // -横线分隔会被转换成驼峰
console.log(myName); // Nicholas
//设置值
div.dataset.appId = 23456; // 设置不了 因为转换成了 appid
div.dataset.myName = "Jack";
if (div.dataset.myName){
alert("Hello, " + div.dataset.myName + " " + div.dataset.appid); // Hello, jack 12345
}
</script>
1、innerHTML
属性
在读模式下返回与调用元素的所有子节点,在写模式下会根据指定的值创建新的DOM
树,然后用这个DOM
树完全替换调用元素原先的所有子节点。在大多数浏览器中,通过innerHTML
插入<script>
元素并不会执行其中的脚本。
2、outerHTML
属性
在读模式下,返回调用它的元素(包含调用元素本身)以及所有子节点的HTML
标签。在写模式下,outerHTML
会根据指定的HTML
字符串创建新的DOM
子树,然后用这个DOM
子树完全替换调用元素。
3、insertAdjacentHTML
方法
将指定的文本解析为HTML
或XML
,并将结果节点插入到DOM
树中的指定位置。它不会重新解析它正在使用的元素,因此它不会破坏元素内的现有元素。这避免了额外的序列化步骤,使其比直接innerHTML
操作更快。
它接收两个参数:插入位置和要插入的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>");
4、内存与性能问题
在删除带有事件处理程序或引用了其他JavaScript
对象子树时,就有可能导致内存占用问题。假设某个元素有一个事件处理程序(或者引用了一个JavaScript
对象作为属性),在使用前述innerHTML
、outerHTML
属性将该元素从文档树中删除后,**元素与事件处理程序(或JavaScript
对象)之间的绑定关系在内存中并没有一并删除。**如果这种情况频繁出现,页面占用的内存数量就会明显增加。因此,在使用innerHTML
、outerHTML
属性和insertAdjacentHTML
方法时,最好先手工删除要被替换的元素的所有事件处理程序和JavaScript
对象属性
不可避免地,创建和销毁HTML
解析器也会带来性能损失,所以最好能够将设置innerHTML
或outerHTML
的次数控制在合理的范围内,所以要尽量避免下面这种操作。
// 要避免这种频繁操作!!
for (var i=0, len=values.length; i < len; i++){
ul.innerHTML += "<li>" + values[i] + "</li>";
}
// 可以先将单独构建字符串,之后一次把结果字符串赋值给innerHTML
var itemsHtml = "";
for (var i=0, len=values.length; i < len; i++){
itemsHtml += "<li>" + values[i] + "</li>";
}
ul.innerHTML = itemsHtml;
scrollIntoView
可以在所有HTML
元素上调用,通过滚动浏览器窗口或某个容器元素,调用元素就可以出现在视口中。接收一个布尔值参数,默认为true
,窗口滚动之后会让调用元素的顶部与视口顶部尽可能平齐。如果传入false
,调用元素会尽可能全部出现在视口中,可能的话,调用元素的底部会与视口顶部平齐,不过顶部不一定平齐。
// 让元素可见
document.forms[0].scrollIntoView();