因为 DOM 的存在,这使我们可以通过 JavaScript 来获取、创建、修改、或删除节点。

    NOTE:下面提供的例子中的 均为元素节点。

    父子关系

    • element.parentNode
    • element.firstChild/element.lastChild
    • element.childNodes/element.children

    兄弟关系

    • element.previousSibling/element.nextSibling
    • element.previousElementSibling/element.nextElementSibling

    通过节点直接的关系获取节点会导致代码维护性大大降低(节点之间的关系变化会直接影响到获取节点),而通过接口则可以有效的解决此问题。

    NTOE:细心地人会发现,在节点遍历的例子中,body、ul、li、p节点之间是没有空格的,因为如果有空格,那么空格就会被当做一个TEXT节点,从而用ulNode.previousSibling获取到得就是一个空的文本节点,而不是 <li>First</li> 节点了。即节点遍历的几个属性会得到所有的节点类型,而元素遍历只会得到相对应的元素节点。一般情况下,用得比较多得还是元素节点的遍历属性。

    实现浏览器兼容版的element.children

    有一些低版本的浏览器并不支持 element.children 方法,但我们可以用下面的方式来实现兼容。

    1. <html lang>
    2. <head>
    3. <title>Compatible Children Method</title>
    4. </head>
    5. <body id="body">
    6. <div id="item">
    7. <div>123</div>
    8. <p>ppp</p>
    9. <h1>h1</h1>
    10. </div>
    11. <script type="text/javascript">
    12. function getElementChildren(e){
    13. if(e.children){
    14. return e.children;
    15. }else{
    16. /* compatible other browse */
    17. var i, len, children = [];
    18. var child = element.firstChild;
    19. while(child != null){
    20. if(child.nodeType == 1){
    21. children.push(child);
    22. }
    23. child = child.nextSibling;
    24. }
    25. }else{
    26. children.push(child);
    27. }
    28. return children;
    29. }
    30. }
    31. /* Test method getElementChildren(e) */
    32. var item = document.getElementById("item");
    33. var children = getElementChildren(item);
    34. for(var i =0; i < children.length; i++){
    35. alert(children[i]);
    36. </script>
    37. </body>
    38. </html>

    NOTE:此兼容方法为初稿,还未进行兼容性测试。

    接口获取元素节点

    • getElementById
    • getElementsByTagName
    • getElementsByClassName
    • querySelector
    • querySelectorAll
    getElementById
    1. var element = document.getElementById('id');
    getElementsByTagName

    动态的获取具有指定标签元素节点的集合(其返回值会被 DOM 的变化所影响,其值会发生变化)。此接口可直接通过元素而获取,不必直接作用于 document 之上。

    1. var collection = element.getElementsByTagName('tagName');
    2. // 获取指定元素的所有节点
    3. var allNodes = document.getElementsByTagName('*');
    4. // 获取所有 p 元素的节点
    5. var elements = document.getElementsByTagName('p');
    6. // 取出第一个 p 元素
    7. var p = elements[0];
    getElementsByClassName

    获取指定元素中具有指定 class 的所有节点。多个 class 可的选择可使用空格分隔,与顺序无关。

    1. var elements = element.getElementsByClassName('className');

    NOTE:IE9 及一下版本不支持 getElementsByClassName

    兼容方法

    querySelector / querySelectorAll

    获取一个 list (其返回结果不会被之后 DOM 的修改所影响,获取后不会再变化)符合传入的 CSS 选择器的第一个元素或全部元素。

    1. var listElementNode = element.querySelector('selector');
    2. var listElementsNodes = element.querySelectorAll('selector');
    3. var sampleSingleNode = element.querySelector('#className');
    4. var sampleAllNodes = element.querySelectorAll('#className');

    NOTE: IE9 一下不支持 querySelectorquerySelectorAll

    创建节点

    创建节点 -> 设置属性 -> 插入节点

    1. var element = document.createElement('tagName');

    textContent

    获取或设置节点以及其后代节点的文本内容(对于节点中的所有文本内容)。

    1. element.textContent; // 获取
    2. element.textContent = 'New Content';

    innerText (不符合 W3C 规范)

    获取或设置节点以及节点后代的文本内容。其作用于 textContent 几乎一致。

    1. element.innerText;

    NOTE:不符合 W3C 规范,不支持 FireFox 浏览器。

    FireFox 兼容方案

    插入节点

    appendChild

    在指定的元素追加一个元素节点。

    1. var aChild = element.appendChild(aChild);

    insertBefore

    在指定元素的指定节点前插入指定的元素。

    1. var aChild = element.insertBefore(aChild, referenceChild);

    删除指定的节点的子元素节点。

    1. var child = element.removeChild(child);

    innerHTML

    获取或设置指定节点之中所有的 HTML 内容。替换之前内部所有的内容并创建全新的一批节点(去除之前添加的事件样式)。innerHTML 不检查内容,直接运行并替换原先的内容。

    NOTE:只建议在创建全新的节点时使用。不可在用户可控的情况下使用。

    • 低版本 IE 存在内存泄露