Css 阻止contenteditable模式创建<;span>;标签
当我在div上使用浏览器contenteditable=true以允许用户更新其中的文本时,我遇到了这个问题(使用Chrome): 使用delete backspace键删除换行符(向上跳行)时,浏览器会在该文本周围插入一个具有内联样式集的标记 这确实令人沮丧,因为它不仅这样做了,还向span标记添加了一个内联样式,例如,如果我的字体颜色当前为黑色,它会向span标记添加一个style=“color:black” 结果是,我无法再使用工具栏编辑该文本的颜色,因为它已被内联样式硬设置为span标记。如果我用delete键备份一行,字体大小也会发生同样的情况 这里的任何人都可以教我一两件关于contenteditable的事情,或者建议一种删除span:s的方法,如果不可能阻止这种浏览器行为的话 **重现这个问题** -在浏览器中创建一个div,在其上设置内联样式,例如字体大小:36px -使用浏览器中可编辑的内容编辑div的文本,使用手动换行符写几行。 -现在,将光标放在文本段落的前面/前面,然后单击backspace。现在应该围绕光标前面的文本生成一个span标记,并更改其样式 更新** 因此,我尝试了几种不同的解决方案,但收效甚微。首先,我试图删除所有标记,但随后我也丢失了所有换行符(也许更好的regexp可以解决这个问题,我不是regexp编写专家) 下面的所有函数都是在keyup事件时首先调用的,但随后我将它们附加到取消选择文本框上。如何激发以下函数与问题无关Css 阻止contenteditable模式创建<;span>;标签,css,html,google-chrome,contenteditable,Css,Html,Google Chrome,Contenteditable,当我在div上使用浏览器contenteditable=true以允许用户更新其中的文本时,我遇到了这个问题(使用Chrome): 使用delete backspace键删除换行符(向上跳行)时,浏览器会在该文本周围插入一个具有内联样式集的标记 这确实令人沮丧,因为它不仅这样做了,还向span标记添加了一个内联样式,例如,如果我的字体颜色当前为黑色,它会向span标记添加一个style=“color:black” 结果是,我无法再使用工具栏编辑该文本的颜色,因为它已被内联样式硬设置为span标记
//option to remove all tags
var withTags = $(textObject).html();
var withoutTags = withTags.replace(/<(?:.|\n)*?>/gm, '');
$(textObject).html(withoutTags);
然后我意识到每次编辑文本框时,chrome可能会添加上面代码无法达到的新嵌套级别的div/span标记,因此我这样做:
//option to remove style of elements
$(textObject).children().each(function() {
$(this).removeAttr('style');
console.log('removing style from first level element: '+this);
//And of course it would be all too easy if chrome added only one level of elements...
$(this).children().each(function() {
$(this).removeAttr('style');
console.log('removing style from second level element: '+this);
});
});
但这还不够,因为理论上筑巢的数量是无限的。仍在努力寻找更好的解决方案。感谢您的任何意见=)目前,我正在使用
$(textObject).find('*').removeAttr('style');
取消选择可编辑区域后
它也可以在按键时使用。伙计,这个问题的时机太疯狂了。我对contenteditable所做的是强制所有内容都位于contenteditable div的段落标记内 因此,我处理这些废话的方法是在每次击键时将每个
展平
由于.text()
选择一个元素的所有文本,包括其子元素,因此我可以(在coffeescript中)进行设置
这解决了我的问题。顺便说一句,这些浏览器实现者真的把contenteditable搞得一团糟。这里有一个巨大的机会让这变得容易,因为这确实是网络的未来。以下是我如何解决这个问题的
我保留所有div、span和p标记的文本,删除这些标记,并用br替换所有div和p。我是在模糊上做的,最好是在每个键下都做,但这消耗了太多的cpu,因为我必须循环所有这些%#·%&(你说的)嵌套元素。问题是,实际上,它不仅插入span和p,而且如果你碰巧复制了一个表,它还会插入整个表,其中包含tbody和行。 所以,我发现唯一能解决这个问题的方法是:
$(document).on("DOMNodeInserted", $.proxy(function (e) {
if (e.target.parentNode.getAttribute("contenteditable") === "true") {
with (e.target.parentNode) {
replaceChild(e.target.firstChild, e.target);
normalize();
}
}
}, this));
是的,它在一定程度上影响了整个页面的性能,但它会阻止将表和内容插入contenteditables
更新:上面的脚本只处理基本情况,即您想要的内容被包装在一个级别的span/p标记中。但是,如果您从Word复制,您甚至可能会复制整个表。 下面是我到目前为止抛出的所有代码:
$(document).on("DOMNodeInserted", $.proxy(function (e) {
if (e.target.parentNode.getAttribute("contenteditable") === "true") {
var newTextNode = document.createTextNode("");
function antiChrome(node) {
if (node.nodeType == 3) {
newTextNode.nodeValue += node.nodeValue.replace(/(\r\n|\n|\r)/gm, "")
}
else if (node.nodeType == 1 && node.childNodes) {
for (var i = 0; i < node.childNodes.length; ++i) {
antiChrome(node.childNodes[i]);
}
}
}
antiChrome(e.target);
e.target.parentNode.replaceChild(newTextNode, e.target);
}
}, this));
$(document).on(“域节点插入”),$.proxy(函数(e){
if(例如,target.parentNode.getAttribute(“contenteditable”)=“true”){
var newTextNode=document.createTextNode(“”);
抗变色功能(节点){
if(node.nodeType==3){
newTextNode.nodeValue+=node.nodeValue.replace(/(\r\n |\n |\r)/gm,“”)
}
else if(node.nodeType==1&&node.childNodes){
对于(变量i=0;i
也可以随意修改中间的正则表达式,以去除你的情况中特别危险的符号。
更新2
经过一段时间的思考和谷歌搜索,我刚刚将上面的代码包装到简单的jQuery插件中,以简化使用。下面是添加样式显示:内联块;对于contenteditable,它不会在chrome中自动生成div、p、span您可以提供一个链接来显示这种情况的示例吗?这种情况发生在哪个浏览器上?元素最初包含什么?当我在元素中键入文本并使用Del键时,我无法在Chrome、Firefox或IE上重现该问题。浏览器在处理输入时输入的方式上有所不同,但这是另一回事。我们也报道了Chrome的错误。实际上,解决这个问题的唯一可靠方法是编写自定义的删除/退格处理程序。你在你的编辑器CK中是如何处理的?我们还没有解决方案。我们一直在等待Chrome团队做出反应,但在过去6个月里,一切都没有改变(甚至变得更糟)。但正如我所写的——唯一好的解决方案是编写自己的删除/退格键处理程序——这是非常棘手的。还有:(另外,我还可以报告更多类似的情况——比如Blink/Webkit在粘贴时产生的垃圾。这样做会不会使换行符松动?还有,这是不是。t
$(document).on("DOMNodeInserted", $.proxy(function (e) {
if (e.target.parentNode.getAttribute("contenteditable") === "true") {
with (e.target.parentNode) {
replaceChild(e.target.firstChild, e.target);
normalize();
}
}
}, this));
$(document).on("DOMNodeInserted", $.proxy(function (e) {
if (e.target.parentNode.getAttribute("contenteditable") === "true") {
var newTextNode = document.createTextNode("");
function antiChrome(node) {
if (node.nodeType == 3) {
newTextNode.nodeValue += node.nodeValue.replace(/(\r\n|\n|\r)/gm, "")
}
else if (node.nodeType == 1 && node.childNodes) {
for (var i = 0; i < node.childNodes.length; ++i) {
antiChrome(node.childNodes[i]);
}
}
}
antiChrome(e.target);
e.target.parentNode.replaceChild(newTextNode, e.target);
}
}, this));