Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 将html转换为保留标记空白含义的文本表示——如何实现?_Javascript_Html_Text_Representation - Fatal编程技术网

Javascript 将html转换为保留标记空白含义的文本表示——如何实现?

Javascript 将html转换为保留标记空白含义的文本表示——如何实现?,javascript,html,text,representation,Javascript,Html,Text,Representation,考虑这样的html片段: <p>foo</p><p>bar</p> 我会很高兴的 foo bar 1 2 它不一定是: foo bar 1 2 (但当然没有造成任何伤害)。您有没有看过这些或属性 function getText(element){ var s = ""; if(element.innerText){ s = element.innerText; }else if(element.t

考虑这样的html片段:

<p>foo</p><p>bar</p>
我会很高兴的

foo bar
1 2
它不一定是:

foo bar
1   2
(但当然没有造成任何伤害)。

您有没有看过这些或属性

function getText(element){
    var s = "";
    if(element.innerText){
        s = element.innerText;
    }else if(element.textContent){
        s = element.textContent;
    }
    return s;
}
范例

将预标记添加到正文并附加正文文本

document.body.appendChild(
    document.createElement('pre')
)
.appendChild(
    document.createTextNode(
        getText(document.body)
    )
);

编辑

在firefox中使用范围是否有效

var r = document.createRange();
r.selectNode(document.body);
console.log(r.toString());

编辑

看起来你被这样的解析函数困住了

var parse = function(element){
    var s = "";
    for(var i = 0; i < element.childNodes.length; i++){
        if(/^(iframe|noscript|script|style)$/i.test(element.childNodes[i].nodeName)){
            continue;
        }else if(/^(tr|br|p|hr)$/i.test(element.childNodes[i].nodeName)){
            s+='\n';
        }else if(/^(td|th)$/.test(element.childNodes[i].nodeName)){
            s+='\t';
        }

        if(element.childNodes[i].nodeType == 3){
            s+=element.childNodes[i].nodeValue.replace(/[\r\n]+/, "");
        }else{
            s+=parse(element.childNodes[i]);
        }
    }
    return s;
}

console.log(parse(document.body)); 
var parse=函数(元素){
var s=“”;
对于(var i=0;i
我开始编写自己的函数,可能是在Zapthedingbat编写的同时,为了记录在案:

var NodeTypeEnum = { Element    : 1,Attribute   : 2, Text:  3, Comment  :8,Document     :9};

function doTextualRepresentation(elem)
{
    if (elem.nodeType==NodeTypeEnum.Text)
        return elem.nodeValue;
    else if (elem.nodeType==NodeTypeEnum.Element || elem.nodeType==NodeTypeEnum.Document)
    {
        var s = "";

        var child = elem.firstChild;
        while (child!=null)
        {
            s += doTextualRepresentation(child);
            child = child.nextSibling;
        }

        if (['P','DIV','TABLE','TR','BR','HR'].indexOf(elem.tagName)>-1)
            s = "\n"+s+"\n";
        else if (['TD','TR'].indexOf(elem.tagName)>-1)
            s = "\t"+s+"\t";

        return s;

    }

    return "";
}

function TextualRepresentation(elem)
{
    return doTextualRepresentation(elem).replace(/\n[\s]+/g,"\n").replace(/\t{2,}/g,"\t");
}
有一件事让我很惊讶,那就是我不能

for (var child in elem.childNodes)

工作,很遗憾,因为我大部分时间都在C#上,而且我喜欢这种语法,理论上它应该在JS中工作,但事实并非如此。

这在很大程度上取决于您的css,一个简单的解决方案是用\n替换结束tr和p标记,用空格替换结束td标记,然后从输入中删除所有html标记。。但这也取决于你的css..我同意lejzz的观点,尽管可能会建议使用一个标签而不是一个空间来放置紧密的td标签,只是为了尽量减少与单元格内空间的混淆。你也可以在foo和bar之间使用\t for tab,然后1和2谢谢大家,它不一定漂亮,它只需做很少的工作,甚至空间也比像
text
那样把所有文本连接在一起要好。你确定在你的测试中,空白不是被网络浏览器压缩了吗?所以你真的得到了
foo-bar
here()?我不。浏览器应该如何确定在何处插入空白?是的,请参见屏幕截图。你在用什么浏览器?Chrome。您只是显示HTML输出(当然,这会在单独的行中显示
foo
bar
,因为它们都在
p
元素中),而不是控制台输出。但无论如何,我注意到
innerText
显然插入了空格,但
textContent
没有。看见考虑到
textContent
是W3C标准,Firefox不支持
innerText
,我不会依赖这种行为。我还测试了FF(未定义+foobar)和Opera(foobar+foobar),因此在主要浏览器中,此解决方案不会插入任何空白(简而言之,这不是解决问题的方法)--它输出原始文本。因为childNodes是一个数组,所以javascript生成数组中每个项的索引,而不是值。您可以使用该语法,但必须这样使用:for(elem.childNodes中的var childIndex){var child=elem.childNodes[childIndex];}
for (var child in elem.childNodes)