contenteditable - 选择2个子段落并写入文本(Firefox Issue)

时间:2014-10-22 22:55:29

标签: javascript jquery html5 wysiwyg contenteditable

我已经在Google上搜索了一个多星期了,我一直在尝试实施不同的解决方案,但没有成功,而且这让我感到很痛苦。

所以你有一个具有多个段落(或同类的其他子元素)的contenteditable div。显然这是你想要保持的那种布局。如果用户选择两个或多个段落并在其上键入文本,则会删除段落并在父div中设置插入符号焦点:

body {
  font-family: georgia;
}
.editable {
  color: red;
}
.editable p {
  color: #333;
}
.editable span {
  color: limegreen !important;
}
<div class="editable" contenteditable><p>paragraph one</p><p>paragraph two</p></div>

<hr>
  
<p>How to reproduce the bug:</p>
<ul>
  <li>Focus the contenteditable above by placing the cursor somewhere in one of the two paragraphs.</li>
  <li>press ctrl-a (in windows or linux) or cmd-a (in osx) to select-all</li>
  <li>type some text</li>
  <li>red text means that the text went directly inside the contenteditable div, black text means it went inside a paragraph</li>
</ul>
  
<p>The correct behaviour should be that that select-all and delete (or "type-over") in a contenteditable with only block tags should leave the cursor inside the first block tag.</p>
  
<p>Webkit gets this right, Firefox gets it wrong.</p>

我在Jquery中尝试过类似的东西:

$(document).on('blur keyup','div[contenteditable="true"]',function(event){
    var sel = window.getSelection();
    var activeElement = sel.anchorNode.parentNode;
    var tagName = activeElement.tagName.toLowerCase();
    if (!(tagName == "p" || tagName == "span")) {
        console.log('not on editable area');
        event.preventDefault();
        //remove window selection
        var doselect = window.getSelection();
        doselect.removeAllRanges();
    }
});

因此,在满足可信度的模糊或键盘事件后,检测插入位置以及它是否在可接受的可编辑区域外停止事件或其他事项?

我已经尝试过改变选择范围,以及其他一些东西,但也许我只是没有看到它。我确信很多人都有同样的问题,但我在谷歌或这里找到的唯一答案是“内容可编辑糟透了”,“为什么你不只是使用开源编辑器”和那种东西。

Firefox奇怪的行为:在断行上插入BR标记 我还尝试使用函数删除Firefox'的奇怪行为,以删除firefox自动插入的所有<BR>标记。像这样:

function removeBr(txteditor) {
    var brs = txteditor.getElementsByTagName("br");
    for (var i = 0; i < brs.length; i++) { brs[i].parentNode.removeChild(brs[i]); }
}

所以我将它附加到keydown事件,并且它完全符合预期,但这会导致更奇怪的行为(比如阻止在所选段落上添加空格)。

请对问题进行投票,以便我们提高认识。

我确信很多其他人遇到了同样的问题,我认为知道是否有解决方法或任何“正确”的方法来做这件事会很好。我认为应该真的讨论......

2 个答案:

答案 0 :(得分:2)

因此,当删除段落时,Firefox会将这种可憎的行为 - <br></br> - 注入到可信的div中。

通过一点点jQuery我们可以删除它并用段落标记替换它。

当前限制 - 只有在删除或退格时才会注入break标记,而不是在输入时注入...考虑这个概念: - )

在Firefox中打开此示例进行测试:

&#13;
&#13;
$("button").click(function() {

 $("br:not(p br)").replaceWith('<p>Write Me!</p>'); // dont replace when inside p
});
&#13;
body {
  font-family: georgia;
}
.editable {
  color: red;
}
.editable p {
  color: #333;
}
.editable span {
  color: limegreen !important;
}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="editable" contenteditable>
  <p>paragraph one</p>
  <p>paragraph two</p>
</div>

<hr>

<p>Remove all text to trigger bug in Firefox and hit "fix problem!"</p>

</ul>

<p>Webkit gets this right, Firefox gets it wrong.</p>

<button class="fix">Fix Problem</button>
&#13;
&#13;
&#13;

答案 1 :(得分:1)

当发生这种情况时,当您选择两组文本并删除它们时,您也会删除可编辑元素中的所有标记。所以你实际上从div中删除<p>标签,然后唯一要写的就是div本身。

为什么需要两个单独的段落标签?单独拥有div会更容易...... 您是否尝试将<p>标记设置为<p contenteditable="true">

,而不是将div设置为可编辑