JavaScript DOM2和DOM3——“遍历”的注重要点

“DOM2级遍历和局限”模块定义了两个用于辅佐完成递次遍历DOM构造的范例:NodeIterator和TreeWalker;这两个范例能够基于给定的出发点对DOM构造实行深度优先的遍历操纵。

NodeIterator范例

运用document.createNodeIterator()要领建立新的实例。这个要领吸收四个参数:

  1. root:想要作为搜刮出发点的树中的节点;

  2. whatToShow:示意要接见哪些节点的数字代码;

  3. filter:是一个NodeFilter对象,或许一个函数(示意应当接收照样谢绝某种特定节点的函数);

  4. entityReferenceExpansion:布尔值,示意是不是扩大实体援用。在HTML页面中没用;

whatToShow:

  1. NodeFilter.SHOW_ALL:一切范例节点;

  2. NodeFilter.SHOW_ELEMENT:元素;

  3. NodeFilter.SHOW_ATTRIBUTE:特征;

  4. NodeFilter.SHOW_TEXT:文本;

  5. NodeFilter.SHOW_COMMENT;

  6. NodeFilter.SHOW_DOCUMENT;

  7. NodeFilter.SHOW_DOCUMENT_TYPE;

别的另有对HTML页面没用的几个:

  • NodeFilter.SHOW_CDATA_SECTION;

  • NodeFilter.SHOW_ENTITY_REFERENCE:实体援用节点;

  • NodeFilter.SHOW_ENTITY:实体节点;

  • NodeFilter.SHOW_PROCESSING_INSTRUCTION:处置惩罚指令节点;

  • NodeFilter.SHOW_DOCUMENT_FRAGMENT;

  • NodeFilter.SHOW_NOTATION:标记节点

能够用按位或操纵符来组合多个选项如:

var whatToShow = NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT;

filter

能够运用createNodeIterator()要领的filter参数来指定自定义的NodeFilter对象,每一个NodeFilter对象只要一个要领,应当接见的节点返回NodeFilter.FILTER_ACCEPT;不应当接见的节点返回NodeFilter.FILTER_SKIP

能够建立包含acceptNode()要领的对象:

var filter = {
    acceptNode: function(node) {
        return node.nodeName.toLowerCase() == "p" ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;
    }
};

也能够建立一个与acceptNode()要领相似的函数:

var filter = function(node) {
    return node.nodeName.toLowerCase() == "p" ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;
}

假如不指定过滤器,那末应当传入null。

举例:

搜刮document中一切的元素

var iterator = document.createNodeIterator(document.body, NodeFilter.SHOW_ELEMENT, null);
var node = iterator.nextNode();
console.log(node); //HTMLBodyElement

搜刮document中一切的p元素

var filter = {
    acceptNode: function(node) {
        return node.nodeName.toLowerCase() == "p" ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;
    }
};
var iterator = document.createNodeIterator(document.body, NodeFilter.SHOW_ALL, filter);
var node = iterator.nextNode();
console.log(node); //HTMLParagraphElement

搜刮document中一切的h1元素

var filter = function(node) {
    return node.nodeName.toLowerCase() == "h1" ? NodeFilter.FILTER_ACCEPT : NodeFilter.FILTER_SKIP;
}
var iterator = document.createNodeIterator(document.body, NodeFilter.SHOW_ALL, filter);
var node = iterator.nextNode();
console.log(node); //HTMLHeadingElement

nextNode()要领与previousNode()要领

前者用于向前行进一步;后者用于向后退却一步。当遍历到DOM子树的末了一个节点时,nextNode()返回null;当遍历到DOM子树的末了一个节点,且previousNode()返回根节点今后,再次挪用它就会返回null。

举例:

以下面的html代码为例:


<div id="div1">
    <p><b>Hello</b> world!</p>
    <ul>
        <li>List item 1</li>
        <li>List item 2</li>
        <li>List item 3</li>
    </ul>
</div>

遍历div元素中一切的节点

var div = document.getElementById("div1");
var iterator = document.createNodeIterator(div, NodeFilter.SHOW_ELEMENT, null, false);
var node = iterator.nextNode();
while(node !== null){
    console.log(node.nodeName); //输出标署名
    node = iterator.nextNode();
}
// [L] repetition.html:24 DIV 
// [L] repetition.html:24 P 
// [L] repetition.html:24 B 
// [L] repetition.html:24 UL 
// [L] repetition.html:24 LI 
// [L] repetition.html:24 LI 
// [L] repetition.html:24 LI 

遍历div中一切的li元素中的文本

var div = document.getElementById("div1");
var filter = function(node) {
    if (node.nodeName.toLowerCase() == "li") {
        return NodeFilter.FILTER_ACCEPT;
    } else {
        return NodeFilter.FILTER_SKIP;
    }
};
var iterator = document.createNodeIterator(div, NodeFilter.SHOW_ELEMENT, filter, false);
var node = iterator.nextNode();
while (node !== null) {
    console.log(node.firstChild.nodeValue);
    node = iterator.nextNode();
}
// [L] repetition.html:31 List item 1 
// [L] repetition.html:31 List item 2 
// [L] repetition.html:31 List item 3 

TreeWalker范例

这个范例比上面谁人更高等,除了包含nextNode()previousNode()在内的雷同的功用以外,这个范例还供应了以下用于在差别方向上遍历DOM构造的要领。如:

  • parentNode():遍历到当前节点的父节点;

  • firstChild():…第一个子节点;

  • lastChild():…末了一个子节点;

  • nextSibling():…当前节点的下一个平辈节点;

  • previousSibling():…当前节点的上一个平辈节点;

createTreeWalker()要领

该要领用于建立TreeWalker对象,document.createTreeWalker()要领吸收4个参数,与document.createNodeIterator()要领一致。个中的currentNode属性,示意任何遍历要领在上一次遍历中返回的招待你。经由过程设置这个属性也能够修正遍历继续进行的节点。如:

var div = document.getElementById("div1");
var walker = document.createTreeWalker(div, NodeFilter.SHOW_ELEMENT, null, false);
var node = walker.currentNode; //currentNode返回当前节点 Div
console.log(node.nodeName); //DIV
walker.currentNode = document.getElementsByTagName("li")[0];
node = walker.currentNode;
console.log(node.firstChild.nodeValue); //List item 1
var secLiElem = walker.nextSibling();
console.log(secLiElem.firstChild.nodeValue); //List item 2

举例:

以下面的html代码为例:


<div id="div1">
    <p><b>Hello</b> world!</p>
    <ul>
        <li>List item 1</li>
        <li>List item 2</li>
        <li>List item 3</li>
    </ul>
</div>

遍历div元素中一切的节点

var div = document.getElementById("div1");
var walker = document.createTreeWalker(div, NodeFilter.SHOW_ELEMENT, null, false);
var node = walker.nextNode();
while(node !== null){
    console.log(node.nodeName);
    node = walker.nextNode();
}
// [L] repetition.html:24 P 
// [L] repetition.html:24 B 
// [L] repetition.html:24 UL 
// [L] repetition.html:24 LI 
// [L] repetition.html:24 LI 
// [L] repetition.html:24 LI 

遍历div元素中一切的li元素中文本

var div = document.getElementById("div1");
var walker = document.createTreeWalker(div, NodeFilter.SHOW_ELEMENT, null, false);
var node = walker.currentNode; //currentNode返回当前节点 Div
walker.firstChild(); //转到p
walker.nextSibling(); //转到ul
node = walker.firstChild(); //转到li
while(node !== null){
    console.log(node.firstChild.nodeValue);
    node = walker.nextNode();
}
// [L] repetition.html:27 List item 1 
// [L] repetition.html:27 List item 2 
// [L] repetition.html:27 List item 3 

因为IE中没有对应的范例和要领,所以运用遍历的夸浏览器解决方案异常少见。

    原文作者:JS菌
    原文地址: https://segmentfault.com/a/1190000004225657
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞