我在SAFARI / CHROME上遇到contenteditable
换行问题。当我在contentEditable <div>
上按“return”,而不是创建<br>
(如Firefox)时,他们会创建一个新的<div>
:
<div>Something</div>
<div>Something</div>
看起来像(在contentEditable DIV上):
Something
Something
但是在消毒后(删除<div>
),我得到了这个:
SomethingSomething
在Firefox中,contenteditable
是:
Something
<br>
Something
在消毒之后看起来是一样的:
Something
Something
是否有任何解决方案可以跨浏览器“规范化”?
我在Make a <br> instead of <div></div> by pressing Enter on a contenteditable
上找到了这段代码$(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中运行了...所有返回{{1对于新行......
现在的问题是,当我在有序或无序列表中时,我需要获得一个没有<br>
的新行......
编辑4:如果有人对上次修改的解决方案感兴趣:Avoid createElement function if it's inside a <LI> element (contentEditable)
答案 0 :(得分:28)
此技术似乎可以避免首次显示BR的Chrome错误(使用您提及的代码,您需要按两次Enter键)。
这不是一个完美的黑客,但它的工作原理:它会在你的BR之后添加一个空格,以便正确显示。
但是,您将看到只添加空格“”不会改变任何内容,它可以与其他字母一起使用。浏览器不会显示它,可能是因为它就像是一个html页面内的空白区域,它根本没有任何意义。为了摆脱这个错误,我创建了一个包含
标记的jQuery div,我使用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;
}
}
});
答案 1 :(得分:13)
听键击似乎很多工作。这样简单的事情是否可行:
var html = $('.content').html().replace(/<div>/gi,'<br>').replace(/<\/div>/gi,'');
JSFiddle demo here。
此外,sanitize.js似乎允许自定义配置。您是否尝试将div
添加为允许元素?
允许HTML / CSS是危险的,因此请确保您格外小心。
编辑:删除了服务器端评论。消毒发生在使用时 - 如果客户想要在本地绕过它,则可以自行承担风险。感谢Vincent McNabb指出这一点。
答案 2 :(得分:9)
您只需使用以下命令即可
document.execCommand('insertHTML',false,'<br>');
此命令将阻止默认行为并添加您希望的标记。 这就是全部,1行代码
更简单的方法。
仅限CSS。
对您来说,应用display:inline-block
规则符合要求
这将只添加 br
答案 3 :(得分:2)
如果Webkits是容器的最后一个(非空)子级,则它不会呈现单个br
。对于Safari,插入换行符的本机键击是Ctrl + Return。仔细观察,您会注意到Safari实际上只插入两个br
,而只渲染一个br
;但是,如果有一些尾随文本,它将插入一个br
,或者一旦你输入一些(如果有双打),它将删除双br
。
显然,似乎Webkits的解决方案是像他们自己一样插入双{{1}},并让他们处理其余的事情。
答案 4 :(得分:1)
您可能想查看css white-space
属性。将样式设置为white-space: pre-wrap
可以让您摆脱所有javascript,因为它会改变要显示的空白行为而不是崩溃。
答案 5 :(得分:0)
答案 6 :(得分:0)
答案 7 :(得分:0)
当您在内容可编辑的 div 中预填充数据并将其重新发送到服务器时,通常会出现这种用例。
例如。 - 就像在社交媒体网站上编辑帖子一样,为了缓解这种情况,我为每个新行创建了新的 div。
let conD =data.postDescription.split('\n');
let conH = "";
conD.forEach((d)=>{
conH +=`<div>${d}</div>`;
});
$("#contentbox").html(conH);