《DOM启蒙》 随笔
使用 Javascript 字符串创建并向 DOM 中添加元素与文本节点
innerHTML、outerHTML、textContent 及 insertAdjacentHTML() 属性和方法提供了使用 Javascript 字符串创建并向 DOM 中添加节点的功能。
复制代码<!DOCTYPE html>
<html lang='en'>
<body>
<div id='A'></div>
<span id='B'></span>
<div id='C'></div>
<div id='D'></div>
<div id='E'></div>
<script>
// 创建一个 strong 元素和文本节点,并添加到 DOM
document.getElementById('A').innerHTML = '<strong>Hi</strong>';
// 创建一个 div 元素和文本节点来替换 <span id='B'></span>
// 注意 span#B 被替换掉了
document.getElementById('B').outerHTML = '<div id="B">replace</div>';
// 创建一个文本节点并用它更新 div#C
document.getElementById('C').textContent = 'update';
// 下面是非标准的扩展 例如,innerText 和 outerText
// 创建一个文本节点,并用它更新 div#D
document.getElementById('D').innerText = 'Keep it';
// 创建一个文本节点,并用它替换 div#E (注意 div#E 没了)
document.getElementById('E').outerText = 'real!';
</script>
</body>
</html>
经过 Javascript 部分的操作后,部分 DOM 树变成了这个样子:
复制代码<div id="A"><strong>Hi</strong></div>
<div id="B">replace</div>
<div id="C">update</div>
<div id="D">Keep it</div>
real!
innerHTML 属性会将字符串中找到的 HTML 元素都转换成实际的 DOM 节点,而 textContent 只能用来构造文本节点。如果你传给 textContent 的字符串包含 HTML 元素,它会直接按文本格式吐出来。
insertAdjacentHTML() 方法仅在 Element 节点上有效,是个比前述方法精准得多的方式。使用这个方法,就可以将节点插入到开标签之前,开标签之后,闭标签之前,以及闭标签之后:
复制代码<!DOCTYPE html>
<html lang='en'>
<body>
<i id='elm'>最近</i>
<script>
var elm = document.getElementById('elm');
elm.insertAdjacentHTML('beforebegin', '<span>A</span>');
elm.insertAdjacentHTML('afterbegin', '<span>B</span>');
elm.insertAdjacentHTML('beforeend', '<span>C</span>');
elm.insertAdjacentHTML('afterend', '<span>D</span>');
</script>
</body>
</html>
执行完 inline 的 Javascript 后, 部分 DOM 树如下:
复制代码<span>A</span>
<i id="elm">
<span>B</span>
最近
<span>C</span>
</i>
<span>D</span>
next:
复制代码<!DOCTYPE html>
<html lang='en'>
<body>
<div id='A'>
<strong>hanzichi</strong>
</div>
<script>
console.log(document.querySelector('#A').innerHTML); // <strong>hanzichi</strong>
console.log(document.querySelector('#A').textContent); // hanzichi
console.log(document.querySelector('#A').innerText); // hanzichi
</script>
</body>
</html>
将 NodeList 或者 HTMLCollection 转换成 Javascript 数组
将节点列表与 HTML 集合转换成真正的 Javascript 数组可以有许多好处。其一,考虑到 NodeList 和 HTMLCollection 都是实时列表,这么做使得我们能够创建该列表的快照,不与实时 DOM 绑定。其二,转换列表成数组可以使用 Array 对象提供的方法。
复制代码// IE8 及之前无效
var arrayOfNodes = Array.prototype.slice.call(someNode.childNodes, 0);
// 兼容
function convertToArray(nodes) {
var array = null;
try {
array = Array.prototype.slice.call(nodes, 0);
} catch(ex) {
array = [];
for (var i = 0, len = nodes.length; i < len; i++)
array.push(nodes[i]);
}
return array;
}
获取文档中当前聚焦/激活节点的引用
使用 document.activeElement,我们可以快速取得文档中聚焦/激活节点的引用。在如下代码中,当页面加载,我们将文档聚焦设为 <textarea>
节点然后使用 activeElement 属性取得该节点的引用:
复制代码<!DOCTYPE html>
<html lang='en'>
<body>
<textarea></textarea>
<script>
document.querySelector('textarea').focus();
console.log(document.activeElement); // <textarea>
</script>
</body>
</html>
使用 document.hasFocus() 方法,可以知道用户当前是否聚焦在加载该 HTML文档的窗口上(并不是判断某元素是否是焦点)。在如下代码中,你可以看到当我们执行代码,然后聚焦在另一个窗口、标签或者应用程序时,getFocus() 会返回 false。
复制代码setTimeout(function() {
console.log(document.hasFocus());
}, 5000);