简体   繁体   English

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

[英]How do I recurse DOM nodes to an arbitrary depth in Javascript?

I am really having trouble getting my head around crossbrowser recursion in the DOM. 我真的很难理解DOM中的跨浏览器递归。 I want to get only the text content of a node, but not any HTML tags or other information. 我只想获取节点的文本内容,而不想要任何HTML标记或其他信息。 Through trial and error, I found that the textContent and innerText attributes don't hold across all browsers, so I have to use the data attribute. 经过反复试验,我发现textContent和innerText属性并不适用于所有浏览器,因此我必须使用data属性。

Now the function I have so far is this: 现在我到目前为止的功能是:

    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;
    },

It's written in object notation, but otherwise it's a pretty standard unremarkable function. 它是用对象表示法编写的,但除此之外,它是一个非常标准的不起眼的功能。 It goes down two levels, which is almost good enough for what I want to do, but I want to "set it and forget it" if possible. 它下降了两个级别,这几乎足以满足我的需求,但我想尽可能地“设置并忘记它”。

I've been at it for four hours and I haven't been able to abstract this to an arbitrary number of levels. 我已经花了四个小时了,但我还不能将其抽象到任意数量的水平。 Is recursion even my best choice here? 递归甚至是我的最佳选择吗? Am I missing a better option? 我是否缺少更好的选择? How would I convert the above function to recurse? 我如何将上述函数转换为递归?

Thanks for any help! 谢谢你的帮助!

Update: I rewrote it per dsfq's model, but for some reason, it goes one level down and is unable to go back up afterwards. 更新:我按照dsfq的模型重写了它,但是由于某种原因,它下降了一层,之后又无法返回。 I realized that my problem previously was that I wasn't concatenating in the second if clause, but this seems to have stopped me short of the goal. 我意识到以前的问题是我没有在第二个if子句中串联,但这似乎使我无法达到目标。 Here is my updated function: 这是我更新的功能:

    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,'');
    },

Anyone see what I'm missing? 有人看到我想念的吗?

Have you considered doing this with jQuery? 您是否考虑过使用jQuery执行此操作?

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

As simple as that! 就如此容易!

It can be really simple function calling itself to to replace nodes with its contents. 这可能是一个非常简单的函数,它自己调用以用其内容替换节点。 For example: 例如:

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]);
        }
    }
}

Looks like in your case you getTextContentXBrowser is a method of some object, so you will need to call it from inside itself properly (in my example I just use function). 看起来在您的情况下, getTextContentXBrowser是某个对象的方法,因此您需要从自身内部正确调用它(在我的示例中,我只使用函数)。

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

Note that this function replaces nodes with a text in place. 请注意,此函数用适当的文本替换节点。 If you want a function that just returns a text without modifying actual node right away consider this example with another version of the script: 如果您想要一个仅返回文本而无需立即修改实际节点的函数,请考虑使用该脚本的另一个版本的示例:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM