如何在各种浏览器中输入后更改contenteditable块的行为

时间:2010-04-29 08:07:22

标签: javascript javascript-events cross-browser contenteditable

当在firefox <div contenteditable="true"> </div>中输入<br />时输入 - 这没关系。但是在Chrome或IE中,会创建新的<div><p>。我该怎么做才能让Chrome和IE的行为像Firefox一样。

5 个答案:

答案 0 :(得分:24)

正如道格拉斯先前所说,当客户在可编辑页面上开始新段落时,浏览器会尝试克隆之前的标记。当浏览器没有任何东西可以脱离时出现差异 - 例如最初页面正文为空时。在这种情况下,不同的浏览器表现不同:IE开始将每个字符串包装成&lt; p&gt;标签,Chrome包装&lt; div&gt;中的每一行。

为了增加跨浏览器体验,WebKit开发人员引入了DefaultParagraphSeparator命令。您可以在Chrome页面加载时使用以下JavaScript将默认段落分隔符更改为&lt; p&gt;标记:

document.execCommand('defaultParagraphSeparator', false, 'p');

答案 1 :(得分:14)

以下内容将在所有主流浏览器中按下回车键时添加<br>,并尝试将插入符号直接放在其后面。但是,WebKit,Opera和IE都存在在<br>之后正确放置插入符号的问题,以下代码不会尝试更正。

function enterKeyPressHandler(evt) {
    var sel, range, br, addedBr = false;
    evt = evt || window.event;
    var charCode = evt.which || evt.keyCode;
    if (charCode == 13) {
        if (typeof window.getSelection != "undefined") {
            sel = window.getSelection();
            if (sel.getRangeAt && sel.rangeCount) {
                range = sel.getRangeAt(0);
                range.deleteContents();
                br = document.createElement("br");
                range.insertNode(br);
                range.setEndAfter(br);
                range.setStartAfter(br);
                sel.removeAllRanges();
                sel.addRange(range);
                addedBr = true;
            }
        } else if (typeof document.selection != "undefined") {
            sel = document.selection;
            if (sel.createRange) {
                range = sel.createRange();
                range.pasteHTML("<br>");
                range.select();
                addedBr = true;
            }
        }

        // If successful, prevent the browser's default handling of the keypress
        if (addedBr) {
            if (typeof evt.preventDefault != "undefined") {
                evt.preventDefault();
            } else {
                evt.returnValue = false;
            }
        }
    }
}

var el = document.getElementById("your_editable_element");

if (typeof el.addEventListener != "undefined") {
    el.addEventListener("keypress", enterKeyPressHandler, false);
} else if (typeof el.attachEvent != "undefined") {
    el.attachEvent("onkeypress", enterKeyPressHandler);
}

答案 2 :(得分:8)

优秀的参考资料位于满意的地方。

http://blog.whatwg.org/the-road-to-html-5-contenteditable

这导致了一个非常好的API http://dev.opera.com/articles/view/rich-html-editing-in-the-browser-part-1/ http://dev.opera.com/articles/view/rich-html-editing-in-the-browser-part-2/

如果您愿意花30分钟到一个小时来阅读所有这些内容,那么您绝对不需要使用像tinyMCE或ckeditor这样糟糕的第三方编辑器,您可以自己构建和自定义它并坦率地说,从头开始比处理第三方WYSIWYG编辑器的所有残缺和不必要的API更容易,更快。

答案 3 :(得分:3)

如果你喜欢快乐而不是追逐错误:-)那么尝试让FF使用p或div也会好得多。不只是因为它被证明是多数投票:-)

原因是,如果你看一个带有XML眼睛的标签(它注入了混合数据模型 - 就像没有被标签保护的文本那样)并且已经存在多年(所有浏览器)完全XML化。

根据您的实际应用程序,可能值得尝试将完整格式的div设置为一些初始内容 - 如果您看到的页面中看到灰色的文本,例如“在此处输入您的评论”并且它消失了你点击它的第二个(或remian - 这是一个设计决定)。

该部分的原因是“contenteditable”的语义是“它已经有内容=&gt;浏览器有足够的信息知道该做什么”所以当浏览器尽力做某事时面对没有内容它使情况更随机。

答案 4 :(得分:2)

我相信如果div里面已经有一个段落标记,并且用户在焦点位于该段落标记内时按下return,那么Firefox将插入另一个。所以,如果你有这个:

<div contenteditable="true">
    <p>&nbsp;</p>
    <p>&nbsp;</p>
</div>

你关注,按回车,Firefox会插入第三段。

您可以通过给予最低高度来解决段落标记中的& nbsp ;,并且您可能只能使用一个。在我最后一次看到这个时,我从未对行为的底部感到满意。您可能需要一些JavaScript来在div中强制执行至少一个段落标记。