Css 阻止contenteditable模式创建<;span>;标签

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标记

当我在div上使用浏览器contenteditable=true以允许用户更新其中的文本时,我遇到了这个问题(使用Chrome):

使用delete backspace键删除换行符(向上跳行)时,浏览器会在该文本周围插入一个具有内联样式集的标记

这确实令人沮丧,因为它不仅这样做了,还向span标记添加了一个内联样式,例如,如果我的字体颜色当前为黑色,它会向span标记添加一个style=“color:black”

结果是,我无法再使用工具栏编辑该文本的颜色,因为它已被内联样式硬设置为span标记。如果我用delete键备份一行,字体大小也会发生同样的情况

这里的任何人都可以教我一两件关于contenteditable的事情,或者建议一种删除span:s的方法,如果不可能阻止这种浏览器行为的话

**重现这个问题** -在浏览器中创建一个div,在其上设置内联样式,例如字体大小:36px -使用浏览器中可编辑的内容编辑div的文本,使用手动换行符写几行。 -现在,将光标放在文本段落的前面/前面,然后单击backspace。现在应该围绕光标前面的文本生成一个span标记,并更改其样式

更新** 因此,我尝试了几种不同的解决方案,但收效甚微。首先,我试图删除所有标记,但随后我也丢失了所有换行符(也许更好的regexp可以解决这个问题,我不是regexp编写专家)

下面的所有函数都是在keyup事件时首先调用的,但随后我将它们附加到取消选择文本框上。如何激发以下函数与问题无关

        //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));