处理contentEditable DIV上的换行符

SAFARI / CHROME上的可用换行符有问题。 当我在contentEditable <div>上按下“return”,而不是像Firefox那样创build一个<br> ,他们创build一个新的<div>

 <div>Something</div> <div>Something</div> 

看起来像(在contentEditable DIV上):

 Something Something 

但是在消毒(去除<div> )后,我得到这个:

 SomethingSomething 

在Firefox中,可以contenteditable是:

 Something <br> Something 

那消毒后看起来是一样的:

 Something Something 

有什么解决scheme可以跨浏览器“规范化”吗?

我发现这个代码是通过在contenteditable上按下Enter来创build一个<br>而不是<div> </ div>

 $(function(){ $("#editable") // make sure br is always the lastChild of contenteditable .live("keyup mouseup", function(){ if (!this.lastChild || this.lastChild.nodeName.toLowerCase() != "br") { this.appendChild(document.createChild("br")); } }) // use br instead of div div .live("keypress", function(e){ if (e.which == 13) { if (window.getSelection) { var selection = window.getSelection(), range = selection.getRangeAt(0), br = document.createElement("br"); range.deleteContents(); range.insertNode(br); range.setStartAfter(br); range.setEndAfter(br); range.collapse(false); selection.removeAllRanges(); selection.addRange(range); return false; } } }); }); 

这工作,但(在SAFARI和CHROME),我不得不按两次“返回”键来得到一个新的线…

任何想法?

编辑 :我发现代码(在这个问题的底部)工作正常,除了“确保一个<br>元素总是lastChild …任何想法如何解决这个问题?

编辑2:我在控制台上得到这个错误: Uncaught TypeError: Object #<HTMLDocument> has no method 'createChild'

编辑3:好吧,我改变了document.createChild("br"); document.createElement("br"); 我想我在FF / Safari / Chrome中工作…所有返回的新行…

现在的问题是,当我在一个有序或无序列表中,我需要得到一个新的行,没有…

编辑4:如果有人对最后编辑的解决scheme感兴趣: 如果它位于<LI>元素(contentEditable)内,请避免使用createElement函数

这种技术似乎可以避免第一次显示BR的Chrome浏览器错误(您提到的代码需要按两次Enter键)。

这不是一个完美的黑客,但它的工作原理:它添加一个空白后,你的BR,所以它显示正常。 但是,你会看到只添加一个空格“”不会改变任何东西,它可以与其他字母一起使用。 浏览器不会显示它,可能是因为它就像是一个html页面中的空白区域,它并不意味着什么。 为了摆脱这个bug,我用jQuery创build了一个div,其中包括一个&nbsp; 标签,我拿text()属性把它放在textnode,否则它不工作。

 $editables = $('[contenteditable=true]'); $editables.filter("p,span").on('keypress',function(e){ if(e.keyCode==13){ //enter && shift e.preventDefault(); //Prevent default browser behavior if (window.getSelection) { var selection = window.getSelection(), range = selection.getRangeAt(0), br = document.createElement("br"), textNode = document.createTextNode("\u00a0"); //Passing " " directly will not end up being shown correctly range.deleteContents();//required or not? range.insertNode(br); range.collapse(false); range.insertNode(textNode); range.selectNodeContents(textNode); selection.removeAllRanges(); selection.addRange(range); return false; } } }); 

听击键似乎很多工作。 像这样简单的事情是可行的:

 var html = $('.content').html().replace(/<div>/gi,'<br>').replace(/<\/div>/gi,''); 

JSFiddle演示在这里 。

另外,它看起来像sanitize.js允许自定义configuration。 你有没有尝试将div添加为允许的元素?

允许HTML / CSS是危险的,所以确保你是谨慎的。

编辑:删除服务器端的意见。 消毒在使用时发生 – 如果客户想要绕过这个地方,可以自行承担风险。 感谢Vincent McNabb指出这一点。

如果它是容器的最后一个(非空的)孩子,Webkit将不会呈现单个br 。 对于Safari,插入换行符的本机按键是Ctrl + Return。 如果仔细观察,您会注意到Safari实际上插入了两个br而只渲染了一个; 然而,如果有一些尾随的文本,它会插入一个单一的br ,或者一旦你input了一些(如果有双打的话)将会删除双重br

显然,Webkits的解决scheme似乎是像自己一样插入双引号,让他们处理剩下的问题。

你可能想检查一下css white-space属性。 将样式设置为white-space: pre-wrap允许您摆脱所有的javascript,因为它会改变空白的行为而不是折叠。

看到这个答案: HTML – 在DIV内容中的换行符可编辑?

看这小提琴

或者这个职位

如何用浏览器兼容性parsing可编辑的DIV文本