在contenteditable中,如何在按下Enter键后在blockquote之后添加段落?

13

我有以下问题:当我在可编辑内容中添加 blockquote 后,按 Enter 键它就会移到新行并添加另一个 blockquote 元素。这样会一直进行下去,我无法摆脱格式。期望的功能类似于无序列表,按 Enter 键会添加一个新的空 <li> 元素,但如果再次按 Enter 键,则可以退出格式,删除先前创建的 <li> 并添加一个 <p>

请查看演示:http://jsfiddle.net/wa9pM/

我找到的一种方法是在创建 blockquote 之前,在 blockquote 下创建一个空的 <p>。但是,是否有一种方法可以使用 JavaScript 打破这种格式行为呢? 我不知道如何检查:如果光标所在位置是行尾,且为 blockquote,则在按 Enter 键时不要添加新的 blockquote

我正在使用以下代码来生成 JS 中的 blockquote

document.execCommand('formatBlock', false, 'blockquote');

我能想到的最好的解决方案是,当按下回车键时触发一个事件。然后确定光标在 contenteditable 中的位置 - 如果光标位于 <br> 后面,则表示在空行上按下了回车键,此时应该跳出 <blockquote>。这对我来说似乎非常复杂。祝你好运。 - Lrdwhyt
3个回答

8

在为iOS应用程序创建富文本编辑器时,我遇到了相同的问题。每次我在文本字段中插入<blockquote>标签并按下Enter键时,都无法摆脱块引用。

经过一番研究,我找到了一个可行的解决方案。

查找内部HTML标签:

function whichTag(tagName){

    var sel, containerNode;
    var tagFound = false;

    tagName = tagName.toUpperCase();

    if (window.getSelection) {

        sel = window.getSelection();

        if (sel.rangeCount > 0) {
            containerNode = sel.getRangeAt(0).commonAncestorContainer;
        }

     }else if( (sel = document.selection) && sel.type != "Control" ) {

         containerNode = sel.createRange().parentElement();

     }

     while (containerNode) {

         if (containerNode.nodeType == 1 && containerNode.tagName == tagName) {

             tagFound = true;
             containerNode = null;

         }else{

             containerNode = containerNode.parentNode;

         }

     }

     return tagFound;
 }

检查块引用标签的出现:

function checkBlockquote(){

    var input = document.getElementById('text_field_id');

    input.onkeydown = function() {

        var key = event.keyCode || event.charCode;

        if( key == 13){

            if (whichTag("blockquote")){

                document.execCommand('InsertParagraph');
                document.execCommand('Outdent');

            }

        }

    };

}

触发按键按下事件:

<body onLoad="checkBlockquote();">
<!-- stuff... -->
</body>

我相信上面的代码可以轻松调整以适应您的需求。如果您需要进一步帮助,请随时问。


1

类似这样的代码可以帮助我完成工作(至少在Chrome和Safari浏览器上)。

演示请见 http://jsfiddle.net/XLPrw/

$("[contenteditable]").on("keypress", function(e) {
    var range = window.getSelection().getRangeAt();
    var element = range.commonAncestorContainer;
    if(element.nodeName == "BLOCKQUOTE") {
        element.parentElement.removeChild(element);   
    }
});

我没有进行过详细的测试,但看起来range.commonAncestorElement返回当前文本节点,如果blockquote包含文本,或者返回blockquote元素本身,如果它不包含文本节点(在Chrome上,会添加一个<br>并将光标定位在其后)。在这种情况下,您可以删除新创建的blockquote。无论如何,在删除元素后,插入符号似乎被定位在contenteditable的某个位置,尽管键入确认它正好位于原始黑体引用之后。希望这能为您指出更具决定性的解决方案。


0

非常晚的答案,但这对我来说是一个简单得多的解决方案。希望它能帮助到其他人。浏览器兼容性可能会有所不同。

YOUR_EDITABLE_ELEMENT.addEventListener('keyup', e => {
  if (e.which || e.keyCode === 13) {
    if (document.queryCommandValue('formatBlock') === 'blockquote') {
      exec('formatBlock', '<P>')
    }
  }
})

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接