检测JavaScript范围对象中的换行符时出现问题

检测JavaScript范围对象中的换行符时出现问题,javascript,newline,range,contenteditable,Javascript,Newline,Range,Contenteditable,我有一些javascript,可以根据用户选择的内容操纵html。对于真正的浏览器,我使用的方法利用了“范围”对象,如下所示: var sel = window.getSelection(); var range = sel.getRangeAt(0); var content = range.toString(); content变量包含所有选定的文本,效果良好。但是,我发现我无法检测结果字符串中的换行符。例如: 所选文本为: abc def ghi range.to

我有一些javascript,可以根据用户选择的内容操纵html。对于真正的浏览器,我使用的方法利用了“范围”对象,如下所示:

    var sel = window.getSelection();
    var range = sel.getRangeAt(0);
    var content = range.toString();
content变量包含所有选定的文本,效果良好。但是,我发现我无法检测结果字符串中的换行符。例如:

所选文本为:

abc

def

ghi

range.toString()的计算结果为“abcdefghi”

对特殊字符的任何搜索都不会返回\n\f\r甚至\s的实例。但是,如果将变量写入可编辑控件,换行符将再次出现

有人知道我错过了什么吗

这些选择和操作可能与可编辑div有关。同样的行为在Chrome、FireFox和Opera中也很明显。令人惊讶的是,IE需要完全不同的代码,但除了IE之外,没有任何问题

非常感谢。

编辑我的帖子:

经过一点实验,我发现
sel.toString()
在contenteditable div中返回新行,而
range.toString()
在正常的不可编辑div中正确返回新行,但在可编辑div中不正确,正如您所报告的那样

但无法找到任何行为的解释


这是一个有用的链接

我找到了至少两种其他方法,因此您仍然可以使用该范围来查找插入符号在Mozilla中的位置

一种方法是打电话

var documentFragment = rangeObj.cloneContents ();
它包含一个childNodes数组,任何换行符都将显示为类“HtmlRelation”的节点


另一种方法是确保每个“br”标记后面都跟一个换行符(0x0a)

这不会以任何可见的方式损害HTML内容,但现在只要调用range.toString(),所有的HTML换行符都会转换为纯文本换行符



我希望这能有所帮助——即使这个话题已经很老了。(我已经是一名亡灵巫师了,呵呵):

多亏了这个操作,我才能够按照他的建议使用window.getSelection()来完成它。我需要获取文本直到InputEvent上的插入符号位置,这给了我一个插入文本的静态范围。所以我有一个范围,但不一定是当前选择的范围

function richToPoorText(range){
    //Caso base, está colapsado.
        console.log(range);
        var restoreRange=document.createRange(); //needed for restoring the caret pos.
        restoreRange.setStart(range[0].endContainer, range[0].endOffset);
        restoreRange.setEnd(range[0].endContainer, range[0].endOffset);
        rangeClone=document.createRange();
        rangeClone.setStart(__baseEditor,0);
        rangeClone.setEnd(range[0].endContainer, range[0].endOffset);
        var str;
        var sel=window.getSelection();
        sel.removeAllRanges();
        sel.addRange(rangeClone);   //sel does converts the br to newlines
        str=sel.toString();
        sel.removeAllRanges();
        sel.addRange(restoreRange);
        return str;

}
非常感谢,如果有人有相同的用例,你可以使用这个snipset


编辑:_baseEditor是一个全局变量,指向编辑器的主要内容Editable div

您所说的“range.toString()计算为“abcdefghi”是什么意思?您使用什么来检查该值?调试器?alert()?您是否使用外部调试器、警报或基于浏览器的调试器将
范围
值写入可编辑控件或
范围.toString()
?@Ben Dunlap上述所有内容。例如,使用VisualStudio访问断点@RaYell-我尝试将range.toString()调用产生的内容写入一个可编辑的div,以证明它维护了换行符信息。第一个答案明确了这一点,sel.toString()有换行符,range.toString()没有。谢谢大家。很好,是的,sel.toString()有新词。非常感谢!解释很简单,并在DOM范围规范中列出:
Range.toString()
仅包括文本节点的内容<代码>
因此不包括块元素隐含的元素和换行符。
document.getSelection().toString()
在IE 11中不起作用。它将所有新行文字合并为一行。你是最好的。这是我见过的最丑陋的JS恐怖表演之一。到目前为止,我一直在寻找一种获取所选文本(包括新行)的方法。非常感谢你!!!使用类似于
[].slice.call(window.getSelection().getRangeAt(0)).reduce(…)
的方法,并用换行符替换
htmlrelation
节点,这是我能够让IE11复制新行的唯一方法。