元素选择
# Selector(选择器)
## getElementBy*
querySelector*
HTML5 向 Web API 新引入了 document.querySelector 以及 document.querySelectorAll 两个方法用来更方便地从 DOM 选取元素,功能类似于 jQuery 的选择器。这使得在编写原生 JavaScript 代码时方便了许多。该方法的浏览器兼容性目前各主流浏览器对此 API 提供了良好支持,IE 需 8+。详情见caniuse。
两个方法使用差不多的语法,都是接收一个字符串参数,这个参数需要是合法的 CSS 选择语法。需要注意的是,传入的选择器参数是要经过字符串转义的,譬如我们有一个类名为为’foo:bar’,所以正确的做法是将反斜杠转义后’.foo\:bar’再传递给 querySelector,后者在接收到’.foo\:bar’这个参数后,字符串将两个反斜杠转义成一个,然后 querySelector 前面得到的一个反斜杠与冒号结合进行转义得到正确结果。
element = document.querySelector('selectors');
elementList = document.querySelectorAll('selectors');
其中参数 selectors 可以包含多个 CSS 选择器,用逗号隔开。
element = document.querySelector('selector1,selector2,...');
elementList = document.querySelectorAll('selector1,selector2,...');
使用这两个方法无法查找带伪类状态的元素,比如 querySelector(’:hover’)不会得到预期结果。不过需要注意的是该系列方法返回的是非实时的结果,想要区别什么是实时非实时的返回结果,请看下例:
//HTML代码<div id="container">
<div></div>
<div></div>
</div>
//首先选取页面中id为container的元素
container=document.getElementById('#container');
console.log(container.childNodes.length)//结果为2
//然后通过代码为其添加一个子元素
container.appendChild(document.createElement('div'));
//这个元素不但添加到页面了,这里的变量container也自动更新了
console.log(container.childNodes.length)//结果为3
通过上面的例子就很好地理解了什么是会实时更新的元素。document.getElementById 返回的便是实时结果,上面对其添加一个子元素后,再次获取所有子元素个数,已经由原来的 2 个更新为 3 个(这里不考虑有些浏览器比如 Chrome 会把空白也解析为一个子节点)。
Polyfill
在 IE7 以及之前的浏览器中,并不能使用 querySelect*等方法,因此需要做以下的 Polyfil:
if (!document.querySelectorAll) {
document.querySelectorAll = function(selectors) {
var style = document.createElement("style"),
elements = [],
element;
document.documentElement.firstChild.appendChild(style);
document._qsa = [];
style.styleSheet.cssText =
selectors +
"{x-qsa:expression(document._qsa && document._qsa.push(this))}";
window.scrollBy(0, 0);
style.parentNode.removeChild(style);
while (document._qsa.length) {
element = document._qsa.shift();
element.style.removeAttribute("x-qsa");
elements.push(element);
}
document._qsa = null;
return elements;
};
}
if (!document.querySelector) {
document.querySelector = function(selectors) {
var elements = document.querySelectorAll(selectors);
return elements.length ? elements[0] : null;
};
}
## 亲属节点
### 父节点
语法:nodeObject.parentNode。其中,nodeObject 为节点对象(元素节点)。例如,获取 id=“demo"的节点的父节点:
document.getElementById("demo").parentNode;
### 兄弟节点
以下属性与元素节点的同级元素相关。
(1)nextElementSibling
nextElementSibling 属性返回指定元素的后一个同级元素,如果没有则返回 null。
// 假定HTML代码如下
// <div id="div-01">Here is div-01</div>
// <div id="div-02">Here is div-02</div>
var el = document.getElementById('div-01');
el.nextElementSibling
// <div id="div-02">Here is div-02</div>
(2)previousElementSibling
previousElementSibling 属性返回指定元素的前一个同级元素,如果没有则返回 null。
### 子节点
1)children
children 属性返回一个类似数组的动态对象(实时反映变化),包括当前元素节点的所有子元素。如果当前元素没有子元素,则返回的对象包含零个成员。
// para是一个p元素节点
if (para.children.length) {
var children = para.children;
for (var i = 0; i < children.length; i++) {
// ...
}
}
(2)childElementCount
childElementCount 属性返回当前元素节点包含的子元素节点的个数。
(3)firstElementChild
firstElementChild 属性返回第一个子元素,如果没有,则返回 null。
(4)lastElementChild
lastElementChild 属性返回最后一个子元素,如果没有,则返回 null。