contenteditable-选择2个子段落并重写文本(Firefox问题)

contenteditable - Selecting 2 child paragraphs and writing text over (Firefox Issue)

本文关键字:文本 Firefox 问题 重写 选择 2个 子段 contenteditable-      更新时间:2023-09-26

我已经在谷歌上搜索了一个多星期了,我一直在尝试实现不同的解决方案,但没有成功,这让我很烦恼。

因此,您有一个包含多个段落(或其他同类子元素)的contenteditablediv。很明显,这是你想要保留的布局。如果用户选择两个或多个段落并在上面键入文本,则会删除这些段落并在父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();
    }
});

因此,在contenteditable上发生模糊或keyup事件后,检测插入符号的位置以及它是否在可接受的可编辑区域之外,是否会停止事件或其他什么?

我试过改变选择范围和其他一些东西,但也许我没有看到。我相信很多人都有同样的问题,但我在谷歌或这里找到的唯一答案是"内容可编辑很糟糕"、"你为什么不使用开源编辑器"等等。

Firefox怪异行为:在换行符上插入BR标记我还试着用一个函数来删除Firefox自动插入的所有<BR>标签,以消除Firefox的怪异行为。像这样:

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

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

请对这个问题投赞成票,以便我们提高认识

我相信很多其他人也遇到过同样的问题,我想知道是否有变通方法或任何"正确"的方法会很好。我认为这真的应该讨论。。。

所以Firefox在删除段落时将这个可憎的<br></br>注入到可编辑内容的div中。

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

当前限制-break标记似乎只有在用delete或backspace删除时才被注入,而不是在。。。把这看作一个概念:-)

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

$("button").click(function() {
 $("br:not(p br)").replaceWith('<p>Write Me!</p>'); // dont replace when inside p
});
body {
  font-family: georgia;
}
.editable {
  color: red;
}
.editable p {
  color: #333;
}
.editable span {
  color: limegreen !important;
}
<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>

发生的事情是,当您选择两组文本并删除它们时,您也将删除可编辑元素中的所有标记。因此,您实际上从div中删除了<p>标记,然后唯一要写入的就是div本身。

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

而不是将div设置为可编辑