阻止contentedable模式创建<span>标记

Mat*_*der 17 html css html5 google-chrome contenteditable

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

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

这实在令人沮丧,因为它不仅会这样做,还会为该span标记添加内联样式,例如,如果我的字体颜色当前为黑色,则会为该span标记添加style ="color:black".

结果是我无法再用我的工具栏编辑该文本的颜色,因为它已通过内联样式很难设置为span标记.如果我使用删除键备份一行,同样的事情发生在字体大小上.

这里的任何人可以教我一两件关于满足的事情,或建议一种方法来消除跨度:s,如果它不可能阻止这种浏览器行为..

**要重现此问题** - 在浏览器中创建一个div,在其上设置内联样式,例如font-size:36px - 使用浏览器中可编辑的内容编辑div的文本,写一些带有手动换行符的行. - 现在将光标放在FRONT OF/FRFORE的一段文本中,然后点击退格键.现在应该在光标前面的文本周围生成一个span标记,并改变它的样式.

更新** 所以我尝试了几种不同的解决方案,但收效甚微.首先我尝试删除所有标签,但之后我也丢失了所有的换行符(也许更好的正则表达式可以解决这个问题,我不是regExp写作的专家).

下面的所有函数首先调用keyup事件,但后来我将它们连接到取消选择文本框.如何解雇以下功能与问题无关.

        //option to remove all tags
        var withTags = $(textObject).html();
        var withoutTags = withTags.replace(/<(?:.|\n)*?>/gm, '');       
        $(textObject).html(withoutTags);
Run Code Online (Sandbox Code Playgroud)

我的第二次尝试更成功,删除文本框下面的对象的样式标记(div添加了文本框内的divs),这是我的第一个代码

        //option to remove style of elements
        $(textObject).children().each(function() {
            $(this).removeAttr('style');
            console.log('removing style from first level element: '+this);

        });
Run Code Online (Sandbox Code Playgroud)

然后我意识到每次编辑文本框时,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);
            });

        });
Run Code Online (Sandbox Code Playgroud)

但这还不够,因为嵌套的数量理论上可以是无限的.仍在努力寻找更好的解决方案.感谢任何输入=)

Вас*_*ков 6

实际上,问题是它不仅会插入span和p,而且如果你碰巧复制了一个表,它会那里插入整个表格,其中包含tbody和rows.所以,我发现为我工作的唯一选择就是:

$(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));
Run Code Online (Sandbox Code Playgroud)

是的,它有点影响了整个页面的性能,但它会阻止将表和内容插入到满足的内容中.

更新:
上述脚本仅处理基本情况,当您希望的内容包含在一个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));
Run Code Online (Sandbox Code Playgroud)

此外,您可以随意修改中间的正则表达式,以删除在您的情况下特别危险的符号.

更新2
经过一段时间的思考和谷歌搜索,我刚刚将上面的代码包装成简单的jQuery插件,以简化使用.这是GitHub链接


Mat*_*der 2

这是我解决这个问题的方法

\n\n

jquery 删除 <span> 标签,同时保留其内容(并用 <br> 替换 <divs> 和 <p>:s)

\n\n

我保留所有 div、span 和 p 标签的文本,删除这些标签,并将所有 div 和 p 替换为 br。我在模糊时执行此操作,最佳方法是在每次按下键时执行此操作,但这会占用太多CPU,因为我必须循环遍历所有这些%#\xc2\xa4\xc2\xa4% & (你说的)嵌套元素。

\n