JavaScript学习笔记(三十八)DOM扩展(二)
HTML5
- HTML5规范包含了与标记相关的大量 JavaSeript API定义。其中有的API与DOM重合,定义了浏览器应该提供的DOM扩展。
一、CSS类扩展
1、getElementByClassName()
该方法暴露在document对象和所有HTML元素上。
- 方法接收一个参数:包含一个或多个类名的字符串;
- 返回类名中包含相应类的元素的NodeList;
- 如果提供了多个类名,则顺序无关紧要。
1
2
3
4
5// 取得所有类名中包含"username"和"current"元素
// 这两个类名的顺序无关紧要
let allCurrentUsernames = document.getElementsByClassName("username current");
// 取得 ID 为"myDiv"的元素子树中所有包含"selected"类的元素
let selected = document.getElementById("myDiv").getElementsByClassName("selected");
在 document上调用getElementsByClassName()返回文档中所有匹配的元素,而在特定元素上调用getElementsByClassName()则返回该元素后代中匹配的元素。
2、classList属性
- classList属性是为了更加方便的对于类名进行增删改查操作。
- classList是一个新的集合类型DOMTokenList的实例。
- 除开length属性,item()和中括号取值等操作外,还增加了以下方法:
- add(value):向类名列表中添加指定的字符串值value。如果这个值已经存在,则什么也不做。
- contains(value):返回布尔值,表示给定的value是否存在。
- remove(value):从类名列表中删除指定的字符串值value。
- toggle(value):如果类名列表中已经存在指定的value,则删除;如果不存在,则添加。
1
2
3
4
5
6
7
8
9
10
11
12
13
14// 删除"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 (let class of div.classList){
doStuff(class);
}
- 添加了classList属性之后,除非是完全删除或完全重写元素的class属性,否则className属性就用不到了。
二、焦点管理
- HTML5增加了辅助DOM焦点管理的功能。首先是document.activeElement,始终包含当前拥有焦点的 DOM元素。
- 页面加载时,可以通过用户输人(按Tab键或代码中使用focus()方法)让某个元素自动获得焦点。
- 默认情况下,document.activeElement在页面刚加载完之后会设置为document.body。而在页面完全加载之前,document.activeElement的值为null。
1 | let button = document.getElementById("myButton"); |
- document.hasFocus()方法,该方法返回布尔值,表示文档是否拥有焦点。
- 确定文档是否获得了焦点,就可以帮助确定用户是否在操作页面。
1 | let button = document.getElementById("myButton"); |
- 这对于保证 Web应用程序的无障碍使用是非常重要的。无障碍Web应用程序的一个重要方面就是焦点管理,而能够确定哪个元素当前拥有焦点(相比于之前的猜测)是一个很大的进步。
三、HTMLDocument扩展
1、readyState属性
- document.readyState属性有两个可能的值:
- loading:表示文档正在加载;
- complete:表示文档加载完成。
- 实际开发中,最好是把 document.readstate当成一个指示器,以判断文档是否加载完毕。
- 通常要依赖onload事件处理程序设置一个标记,表示文档加载完了。
1 | if (document.readyState == "complete"){ |
2、compatMode属性
- 这个属性唯一的任务是指示浏览器当前处于什么渲染模式。
- 标准模式下document.compatMode的值是“CSSlCompat”。
- 混杂模式下document.compatMode的值是“BlackCompat”。
1 | if (document.compatMode == "CSS1Compat"){ |
3、head属性
- document.head属性指向文档的
<head>
元素。
1 | let head = document.head; |
四、字符集属性
- characterSet属性表示文档实际使用的字符集,也可以用来指定新字符集。
- 属性的默认值是“UTF-16”,可以通过
<meta>
元素或响应头以及新增的characterSeet属性来修改。
1 | console.log(document.characterSet); // "UTF-16" |
五、自定义数据属性
- HTML5允许给元素指定非标准的属性,但要使用前缀data-以便告诉浏览器,这些属性既不包含与渲染有关的信息,也不包含元素的语义信息。
- 除了前缀,自定义属性对命名是没有限制的,data-后面跟什么都可以。
1 | <div id="myDiv" data-appId="12345" data-myname="Nicholas"></div> |
- 定义了自定义数据属性后,可以通过元素的dataset属性来访问。dataset属性是一个DOMStringMap的实例,包含一组键/值对映射。
- 元素的每个data-name 属性在dataset 中都可以通过data-后面的字符串作为键来访问(例如,属性data-myname,data-myName可以通过myname访问,但要注意data-my-name、data-My-Name要通过myName 来访问)。
1 | // 本例中使用的方法仅用于示范 |
六、插入标记
- 在所有现代浏览器中,通过innerHTML插入的
<script>
标签是不会执行的。
1、innerHTML属性
在读取innerHTML属性时,会返回元素所有后代的HTML字符串,包括元素、注释和文本节点。
在写入innerHTML时,则会根据提供的字符串值以新的DOM子树替代元素中原来包含的所有节点。
比如下面的 HTML 代码:
1
2
3
4
5
6
7
8<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>
元素而言,其 innerHTML 属性会返回以下字符串:1
2
3
4
5
6<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>实际返回的文本内容会因浏览器而不同:
- IE 和 Opera 会把所有元素标签转换为大写;
- Safari、Chrome和 Firefox 会按照文档源代码的格式返回,包含空格和缩进。
在写人模式下,赋给innerHTML属性的值会被解析为DOM子树,并替代元素之前的所有节点。如果赋值中不包含任何HTML标签,则直接生成一个文本节点。
- 因为所赋的值默认为HTML,所以其中的所有标签都会以浏览器处理HTML的方式转换为元素(同样,转换结果也会因浏览器不同而不同)。
1
div.innerHTML = "Hello world!";
- 因为所赋的值默认为HTML,所以其中的所有标签都会以浏览器处理HTML的方式转换为元素(同样,转换结果也会因浏览器不同而不同)。
因为浏览器会解析设置的值,所以给innerHTML, 设置包含HTML的字符串时,结果会大不一样。
1
div.innerHTML = "Hello & welcome, <b>\"reader\"!</b>";
1
<div id="content">Hello & welcome, <b>"reader"!</b></div>
设置innerHTML会导致浏览器将HTML字符串解析为相应的DOM树。这意味着设置innerHTML属性后马上再读出来会得到不同的字符串。这是因为返回的字符串是将原始字符串对应的 DOM子树序列化之后的结果。
2、outerHTML属性
- 读取 outerHTML属性时,会返回调用它的元素(及所有后代元素)的 HTML字符串。
- 在写入outerHTML属性时,调用它的元素会被传入的 HTML字符串经解释之后生成的 DOM子树取代。
- 如果使用outerHTML设置HTML,比如:会得到与执行以下脚本相同的结果:
1
div.outerHTML = "<p>This is a paragraph.</p>";
新的1
2
3let p = document.createElement("p");
p.appendChild(document.createTextNode("This is a paragraph."));
div.parentNode.replaceChild(p, div);<p>
元素会取代 DOM 树中原来的<div>
元素。
3、insertAdjacentHTML()与insertAdjacentText()
- 这两个方法都接收两个参数:
- 要插入标记的位置;
- 要插入的HTML或文本。
- 第一个参数必须是下列值中的一个:
- beforebegin:插入当前元素前面,作为前一个同胞节点;
- afterbegin:插入当前元素内部,作为新的子节点或放在第一个子节点前面;
- beforeend:插入当前元素内部,作为新的子节点或放在最后一个子节点后面;
- afterend:插入当前元素后面,作为下一个同胞节点。
- 这几个值是不区分大小写的。第二个参数会作为HTML字符串解析(与innerHTML 和outerHTML相同)或者作为纯文本解析(与innerText和outerText相同)。 如果是HTML,则会在解析出错时抛出错误。
1 | // 作为前一个同胞节点插入 |
4、内存与性能问题
- 使用以上方法替换子节点可能在浏览器(特别是IE)中导致内存问题。
七、scrollIntoView()
- DOM规范中没有涉及的一个问题是如何滚动页面中的某个区域。为填充这方面的缺失,不同浏览器实现了不同的控制滚动的方式。在所有这些专有方法中,HTML5选择了标准化scrollIntoView()。
- scrollIntoView()方法存在于所有HTML元素上,可以滚动浏览器窗口或容器元素以便包含元素进入视口。参数如下:
- alignToTop是一个布尔值:
- true:窗口滚动后元素的顶部与视口顶部对齐。
- false:窗口滚动后元素的底部与视口底部对齐。
- scrollIntoViewOptions是一个选项对象:
- behavior:定义过渡动画,可取的值为” smooth”和”auto”,默认为”auto”。
- block:定义垂直方向的对齐,可取的值为“start”、“center”、“end”和“nearest”,默认为“start”。
- inline:定义水平方向的对齐,可取的值为“start”、“center”、“end”和“nearest”,默认为“nearest”。
- 不传参数等同于alignToTop为true。
- alignToTop是一个布尔值:
1 | // 确保元素可见 |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 姚永坤的小窝!
评论