如何在Javascript中将DOM节点递归到任意深度?

时间:2014-03-03 09:17:23

标签: javascript dom recursion

我真的很难理解DOM中的crossbrowser递归。我想只获取节点的文本内容,而不是任何HTML标签或其他信息。通过反复试验,我发现textContent和innerText属性并不适用于所有浏览器,所以我必须使用data属性。

现在我的功能是:

    getTextContentXBrowser: function(nodeIn) {
        // Currently goes down two levels. Need to abstract further to handle arbitrary number of levels
        var tempString = '';
        for (i=0, len=nodeIn.childNodes.length; i < len; i++) {
            if (nodeIn.childNodes[i].firstChild !== null) {
                tempString += nodeIn.childNodes[i].firstChild.data;
            } else {
                if (nodeIn.childNodes[i].data && nodeIn.childNodes[i].data !== '\n') {
                    tempString += nodeIn.childNodes[i].data;
                }
            }
        }
        return tempString;
    },

它是用对象表示法编写的,但除此之外它是一个非常标准的不起眼的功能。它下降了两个级别,这几乎足以满足我的目的,但如果可能的话,我想“设置并忘记它”。

我已经四个小时了,我无法将其抽象为任意数量的级别。递归是我最好的选择吗?我错过了更好的选择吗?我如何将上述函数转换为递归?

感谢您的帮助!

更新:我根据dsfq的模型改写了它,但由于某种原因,它会降低一级,之后无法恢复。我意识到我之前的问题是我没有在第二个if子句中连接,但这似乎阻止了我的目标。这是我更新的功能:

    getTextContentXBrowser: function(nodeIn) {
        var tempString = '';
        for (i=0, len=nodeIn.childNodes.length; i < len; i++) {
            if (nodeIn.childNodes[i].data) {
                tempString += nodeIn.childNodes[i].data;
            } else if (nodeIn.childNodes[i].firstChild) {
                tempString += this.getTextContentXBrowser(nodeIn.childNodes[i]);
            }
        }
        return tempString.replace(/ /g,'').replace(/\n/g,'');
    },

任何人都能看到我错过的东西吗?

2 个答案:

答案 0 :(得分:1)

您是否考虑过使用jQuery执行此操作?

getTextContentXBrowser: function(nodeIn) {
    return $(nodeIn).text();
}

就这么简单!

答案 1 :(得分:1)

它可以是一个非常简单的函数,用于将节点替换为其内容。例如:

function flatten(node) {
    for (var c = node.childNodes, i = c.length; i--;) {
        if (c[i].nodeType == 1) {
            c[i].parentNode.replaceChild(document.createTextNode(flatten(c[i]).innerHTML), c[i]);
        }
    }
}

在您的情况下,getTextContentXBrowser看起来是某个对象的方法,因此您需要从内部正确调用它(在我的示例中,我只是使用函数)。

演示:http://jsfiddle.net/7tyYA/

请注意,此函数会替换具有文本的节点。如果你想要一个只返回文本但不立即修改实际节点的函数,请考虑使用另一个版本的脚本这个例子:

演示2:http://jsfiddle.net/7tyYA/1/