通用的HTML文档DOM树遍历函数

目录

前言

  本篇记录《JavaScript权威指南》中提供的通用性的DOM结构遍历函数,这是十分常用的场景,可以获取除了Text节点以外的全部文档节点。


实现

parent函数

  • 返回元素e的第n层祖先元素,如果不存在则返回null
  • 如果n===0;返回e本身;n===1,返回父节点,以此类推
    1
    2
    3
    4
    5
    6
    function parent(e, n) {
    if (n === undefined) n = 1;
    while(n-- && e) e = e.parentNode;
    if (!e || e.nodeType !== 1) return null;
    return e;
    }

sibling函数

  • 返回元素e的第n个兄弟元素
  • n>0,返回后续元素
  • n<0,返回x先前元素
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    function sibling(e,n) {
    while(e && n !== 0) { // If e is not defined we just return it
    if (n > 0) { // Find next element sibling
    if (e.nextElementSibling) e = e.nextElementSibling;
    else {
    for(e=e.nextSibling; e && e.nodeType !== 1; e=e.nextSibling)
    /* empty loop */ ;
    }
    n--;
    }
    else { // Find the previous element sibling
    if (e.previousElementSibing) e = e.previousElementSibling;
    else {
    for(e=e.previousSibling; e&&e.nodeType!==1; e=e.previousSibling)
    /* empty loop */ ;
    }
    n++;
    }
    }
    return e;
    }

child函数

  • 返回元素e的第n个子元素,如果不存在则返回null
  • 如果n===0;返回第一个子元素;n===-1,返回最后一个子元素,-2表示倒数第二个,以此类推
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    function child(e, n) {
    if (e.children) { // If children array exists
    if (n < 0) n += e.children.length; // Convert negative n to array index
    if (n < 0) return null; // If still negative, no child
    return e.children[n]; // Return specified child
    }

    // If e does not have a children array, find the first child and count
    // forward or find the last child and count backwards from there.
    if (n >= 0) { // n is non-negative: count forward from the first child
    // Find the first child element of e
    if (e.firstElementChild) e = e.firstElementChild;
    else {
    for(e = e.firstChild; e && e.nodeType !== 1; e = e.nextSibling)
    /* empty */;
    }
    return sibling(e, n); // Return the nth sibling of the first child
    }
    else { // n is negative, so count backwards from the end
    if (e.lastElementChild) e = e.lastElementChild;
    else {
    for(e = e.lastChild; e && e.nodeType !== 1; e=e.previousSibling)
    /* empty */;
    }
    return sibling(e, n+1); // +1 to convert child -1 to sib 0 of last
    }
    }