Selectors API
- querySelector(cssSelector): 参数为css selector, 返回与模式匹配的第一个元素,如果没有找到元素,返回null
通过Document调用querySelector, 会在文档元素的范围内查找匹配的元素;
通过Element调用querySelector,会在该元素后代元素的范围内查找匹配的元素
<p>sunny day</p>
<div id="myDiv">
<p>hello</p>
</div>
document.querySelector('p')
// <p>sunny day</p>
document.querySelector('#myDiv')
// <div id="myDiv"><p>hello</p></div>
document.querySelector('#myDiv').querySelector('p')
//<p>hello</p>
- querySelectorAll(cssSelector): 类似querySelector, 但返回的是NodeList, 没有找到匹配的元素就返回空的NodeList, 而且可以一次查询多个selector, 使用逗号分隔
<div class="thing">A thing</div>
<div class="thing">A thing</div>
<div class="another-thing">Another thing</div>
let allThings = document.querySelectorAll('.thing, .another-thing')
Tips: 现代浏览器可以直接使用NodeList.forEach, 如果是旧版浏览器,需要使用Array.from(arrayLike)将nodeList转换为array
// Modern browsers
let allThings = document.querySelectorAll('.thing, .another-thing')
allThings.forEach(el => {/* do something with element */})
// Older browsers
let allThings = document.querySelectorAll('.thing, .another-thing')
// You might need a polyfill for Array.from.
// Alternatively, use Array.prototype.slice.call(allThings);
let allThingsArray = Array.from(allThings, (item, index) => {
/* do something with element */
})
// 或者使用forEach
allThingsArray.forEach(el => {/* do something with element */})
元素遍历
childElementCount: 返回子元素(不包括文本节点和注释)的个数
firstElementChild: 指向第一个子元素(firstChild的元素版)
lastElementChild: 指向最后一个子元素(lastChild的元素版)
previousElementSibling: 指向前一个同辈元素(previousSibling的元素版)
nextElementSibling: 指向后一个同辈元素(nextSibling的元素版)
HTML5 DOM扩展
getElementsByClassName():只有位于调用元素子树中的元素才会返回,在document上调用,会返回文档中与类名匹配的元素
classList: 新集合类型DOMTokenList的实例,通过className属性添加、删除和替换
- add(value)
- contains(value)
- remove(value)
- toggle(value)
焦点管理(主要用途是提高Web应用的无障碍性):
document.activeElement // 返回DOM中获得了焦点的元素, 没有时返回null
document.hasFocus() // 判断文档是否获得了焦点
HTMLDocument变化
文档状态:
document.readyState // 两个可能值:‘loading’, 'complete'
兼容模式:
document.compatMode // 两个可能值: ‘CSS1Compat’ 为标准模式,'BackCompat' 为混杂模式
head引用:
document.head // 引用文档的<head>元素
兼容写法:
let head = document.head || document.getElementsByTagName('head')[0]
字符集:
document.charset = 'utf-8' // 文档字符集,默认为utf-16
自定义数据属性:
<div id="myDiv" data-appId="1234" data-myName="Nicholas"></div>
插入标记:
innerHTML属性: 返回调用元素的所有子节点(包括元素、注释、文本节点)对应的HTML标记。在插入之前,需要检查文本内容是否有害, htmlEncode转换"<", ">", "\'", "\"", "&" , " "等特殊字符
具体转码的方法可以参考文章:http://www.cnblogs.com/xdp-gacl/p/3722642.html
outerHTML属性: 与innerHTML的区别,outerHTML返回调用元素本身和子元素对应的HTML标记
insertAdjacentHTML()方法:两个参数,插入的位置和文本
beforebegin: 作为前兄弟节点插入
afterbegin: 作为第一个子元素插入
beforeend: 作为最后一个子元素插入
afterend: 作为后兄弟节点插入
内存与性能: 在删除带有事件处理程序或引用了其他Javascript对象子树时,就有可能导致内存占用问题,因此,在使用innerHTML、outerHTML属性和insertAjacentHTML() 方法时,最好先手动删除要被替换的元素的所有事件处理程序和引用的Javascript对象
/* 要尽量避免下面这种频繁操作innerHTML的方法 */
for (let i = 0, len = values.length; i < len; i++) {
ul.innerHTML += `<li>${values[i]}</li>`;
}
/* 下面这种一次性赋值给innerHTML则高效很多 */
let itemHtml = ''
for (let i = 0, len = values.length; i < len; i++) {
itemHtml += `<li>${values[i]}</li>`;
}
ul.innerHTML = itemHtml
scrollIntoView() 方法:应用在HTML元素上,调用该方法的元素可以出现在视口中
document.forms[0].scrollIntoView(); // 传入true: 元素顶部和视口顶部平行; false: 元素尽可能全部出现在视口中
具体参考https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView
专有扩展
文档模式
IE8引入了“文档模式”的概念,页面的文档模式决定了可以使用哪个级别的CSS, 可以在Javascript中使用哪些API, 以及如何对待文档类型(doctype), 到IE9, 共有4种文档模式
IE5:以混杂模式渲染页面
IE7:以IE7标准模式渲染页面
IE8:以IE8标准模式渲染页面,可以使用Selectors API, 更多CSS2级选择符和某些CSS3功能,还有一些H5的功能
IE9:以IE9标准模式渲染页面,可以使用ECMAScript 5, 完整的CSS3及更多的H5
要强制浏览器以某种模式渲染页面,可以使用HTTP头部信息X-UA-Compatible,或通过等价的<meta>标签
<meta http-equiv="X-UA-Compatible" content="IE=IEVersion" />
<meta http-equiv="X-UA-Compatible" content="IE=Edge, Chrome=1" /> // 优先使用Chrome浏览器渲染页面,如果是IE浏览器,则忽略文档类型,始终以最新的文档模式渲染页面
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" /> // 如果有文档类型声明,则以IE7标准模式渲染页面,否则将文档模式设置为IE5
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" /> // 忽略文档类型声明,强制以IE7标准模式渲染页面
children属性:类似childNodes, 但只包含元素的元素子节点
contains() 方法:判断某个节点是不是另一个节点的子节点
document.documentElement.contains(document.body) // true
innerText 属性:操作元素中包含的所有文本内容,包括子文档树中的文本,读取时,会由浅入深,将子文档树中的所有文本拼接起来;写入时,会对HTML编码(<, >, 空格,‘ “引号,&和号),确保生成一个子文本节点, 但Firefox不支持innerText, 可以使用textContent属性(DOM Level3规定的一个属性), textContent与innerText不同的是,textContent会返回行内样式和脚本代码
// 读取元素文本子节点内容
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 属性:读取时,和innerText的结果一样,写入时,outerText会替换调用它的元素,包括元素的子节点,同样Firefox不支持该属性。因为写入会导致调用它的元素不存在,因此,不建议使用该属性