【问题标题】:In contenteditable how do you add a paragraph after blockquote on Enter key press?在 contenteditable 中,如何在按 Enter 键的块引用之后添加段落?
【发布时间】:2013-01-18 00:46:44
【问题描述】:

我有以下问题。一旦我在contenteditable 中添加了blockquote,通过按Enter 键它会移动到新行并添加另一个blockquote 元素。它永远持续下去,我无法逃避格式化。所需的功能将是无序列表的功能。当您按 Enter 键时,它会添加一个新的空 <li> 元素,但如果您再次按 Enter,它会转义格式,删除之前创建的 <li> 并添加一个 <p>

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

我发现的一个技巧是在创建blockquote 之前在blockquote 下创建一个空的<p>。但是有没有办法用 JavaScript 打破这种格式化行为?不知道我将如何检查:如果光标在哪里,它是行尾,如果它是一个块引用并且在 Enter 键按下时,不要添加新的blockquote

我正在使用这段代码在 JS 中生成blockquote

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

【问题讨论】:

  • 我能想到的最佳解决方案是在按下回车键时触发一个事件。然后确定光标在 contenteditable 中的位置 - 如果它在 <br> 之后,则它被按下在空白行上,然后应该从 <blockquote> 中跳出。请注意,这对我来说似乎很复杂。祝你好运。

标签: javascript html contenteditable paragraph


【解决方案1】:

在为 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>

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

【讨论】:

    【解决方案2】:

    这样的事情对我有用(至少在 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 上,添加了 &lt;br&gt;并且插入符号位于它之后)。在这种情况下,您可以删除新创建的块引用。无论如何,在删除元素后,插入符号看起来像是定位在 contenteditable 上的某个位置,尽管键入确认它就在原始黑引号之后。 希望这可以为您提供一个更有说服力的解决方案。

    【讨论】:

      【解决方案3】:

      超级迟到的答案,但这对我来说是一个更简单的解决方案。希望它可以帮助其他人寻找。浏览器兼容性可能会有所不同。

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

      【讨论】:

        猜你喜欢
        • 2011-01-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-09-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多