4

我需要创建一个数组,其中包含没有 jQuery 的页面中的所有文本。这是我的html:

<html>
<head>
    <title>Hello world!</title>
</head>
<body>
    <h1>Hello!</h1>
    <p>
        <div>What are you doing?</div>
        <div>Fine, and you?</div>
    </p>
    <a href="http://google.com">Thank you!</a>
</body>
</html>

这是我想要得到的

text[1] = "Hello world!";
text[2] = "Hello!";
text[3] = "What are you doing?";
text[4] = "Fine, and you?";
text[5] = "Thank you!";

这是我尝试过的,但在我的浏览器中似乎无法正常工作:

var elements = document.getElementsByTagName('*');
console.log(elements);

PS。我需要使用 document.getElementsByTagName('*'); 并排除“脚本”和“样式”。

4

5 回答 5

5
  var array = [];

    var elements = document.body.getElementsByTagName("*");

    for(var i = 0; i < elements.length; i++) {
       var current = elements[i];
        if(current.children.length === 0 && current.textContent.replace(/ |\n/g,'') !== '') {
           // Check the element has no children && that it is not empty
           array.push(current.textContent);
        }
    } 

你可以做这样的事情

演示

结果 =["What are you doing?", "Fine, and you?"]

或者你可以使用document.documentElement.getElementsByTagName('*');

还要确保你的代码在这个里面

document.addEventListener('DOMContentLoaded', function(){

   /// Code...
});

如果它只是你需要的标题,你也可以这样做

array.push(document.title);

保存循环脚本和样式

于 2013-07-18T15:44:28.117 回答
2

如果你想要整个页面的内容,你应该可以使用

var allText = document.body.textContent;

在IE9之前的Internet Explorer中,有innerText类似但不完全相同的属性。MDN page abouttextContent有更多详细信息。

现在这里的一个问题是,textContent它将为您提供任何<style><script>标签的内容,这可能是您想要的,也可能不是您想要的。如果你不想这样,你可以使用这样的东西:

function getText(startingPoint) {
  var text = "";
  function gt(start) {
    if (start.nodeType === 3)
      text += start.nodeValue;
    else if (start.nodeType === 1)
      if (start.tagName != "SCRIPT" && start.tagName != "STYLE")
        for (var i = 0; i < start.childNodes.length; ++i)
          gt(start.childNodes[i]);
  }
  gt(startingPoint);
  return text;
}

然后:

var allText = getText(document.body);

注意:这(或document.body.innerText)将为您提供所有文本,但以深度优先的顺序。按照页面渲染后人类实际看到的顺序从页面中获取所有文本是一个更加困难的问题,因为它需要代码来理解布局的视觉效果(和视觉语义!)由 CSS(等)决定。

编辑-如果您希望将文本“存储到数组中”,我想在逐个节点的基础上(?),您只需将数组附加替换为上面的字符串连接:

function getTextArray(startingPoint) {
  var text = [];
  function gt(start) {
    if (start.nodeType === 3)
      text.push(start.nodeValue);
    else if (start.nodeType === 1)
      if (start.tagName != "SCRIPT" && start.tagName != "STYLE")
        for (var i = 0; i < start.childNodes.length; ++i)
          gt(start.childNodes[i]);
  }
  gt(startingPoint);
  return text;
}
于 2013-07-18T15:46:23.363 回答
1

似乎是一个单行解决方案(小提琴):

document.body.innerHTML.replace(/^\s*<[^>]*>\s*|\s*<[^>]*>\s*$|>\s*</g,'').split(/<[^>]*>/g)

但是,如果 中有复杂的脚本,这可能会失败body,而且我知道用正则表达式解析 HTML不是一个非常聪明的主意,但对于简单的情况或演示目的,它仍然可以适用,不是吗?:)

于 2013-07-18T16:32:40.887 回答
0

遍历 DOM 树,获取所有文本节点,获取文本节点的 nodeValue。

var result = [];
var itr = document.createTreeWalker(
    document.getElementsByTagName("html")[0],
    NodeFilter.SHOW_TEXT,
    null, // no filter
    false);
while(itr.nextNode()) {
    if(itr.currentNode.nodeValue != "")
        result.push(itr.currentNode.nodeValue);
}
alert(result);

替代方法:拆分 HTML 标记的 textContent。

var result = document.getElementsByTagName("html")[0].textContent.split("\n");
for(var i=0; i<result.length; i++)
    if(result[i] == "")
        result.splice(i, 1);
alert(result);
于 2013-07-18T15:59:55.867 回答
0
    <html>
    <head>
            <title>Hello world!</title>
    </head>
    <body>
            <h1>Hello!</h1>
            <p>
                    <div>What are you doing?</div>
                    <div>Fine, 
                        <span> and you? </span>
                    </div>
            </p>
            <a href="http://google.com">Thank you!</a>
            <script type="text/javascript">
                function getLeafNodesOfHTMLTree(root) {
                    if (root.nodeType == 3) {
                        return [root];
                    } else {
                        var all = [];
                        for (var i = 0; i < root.childNodes.length; i++) {
                            var ret2 = getLeafNodesOfHTMLTree(root.childNodes[i]);
                            all = all.concat(ret2);
                        }
                        return all;
                    }
                }
                var allnodes = getLeafNodesOfHTMLTree(document.getElementsByTagName("html")[0]);
                console.log(allnodes);
                 //in modern browsers that surport array filter and map
                allnodes = allnodes.filter(function (node) {
                    return node && node.nodeValue && node.nodeValue.replace(/\s/g, '').length;
                });
                allnodes = allnodes.map(function (node) {
                    return node.nodeValue
                })
                 console.log(allnodes);
            </script>
    </body>
    </html>
于 2013-07-18T15:49:55.050 回答