如何使 HTML5 contenteditable div 只允许在 firefox 中使用文本?

问题描述 投票:0回答:3

我想制作带有 contentEditable 属性的 div,该属性只允许文本。在 Chrome 中可以通过使用以下方法轻松实现:

<div contenteditable="plaintext-only"></div>

但是它在 Firefox 中不起作用。有没有办法在 Firefox 中制作纯文本 contenteditable div ?我知道这是可能的,因为 Google Plus 有这样的 div,但我不知道他们是如何做到的。

html contenteditable
3个回答
12
投票

我自己也遇到过这个问题。这是我在 Firefox 和 Chrome 中测试过的解决方案:

确保

contenteditable
div 具有 css
white-space: pre
pre-line
pre-wrap
,以便将
\n
显示为新行。

覆盖“enter”键,这样当我们输入时,它就不会创建任何

<div>
<br>
标签

myDiv.addEventListener("keydown", e => {
    //override pressing enter in contenteditable
    if (e.keyCode == 13)
    {
        //don't automatically put in divs
        e.preventDefault();
        e.stopPropagation();
        //insert newline
        insertTextAtSelection(myDiv, "\n");
    }
});

其次,覆盖粘贴事件以仅获取明文

//override paste
myDiv.addEventListener("paste", e => {
    //cancel paste
    e.preventDefault();
    //get plaintext from clipboard
    let text = (e.originalEvent || e).clipboardData.getData('text/plain');
    //insert text manually
    insertTextAtSelection(myDiv, text);
});

这里是支持函数,它将文本插入到div的textContent中,然后将光标返回到正确的位置。

function insertTextAtSelection(div, txt) {
    //get selection area so we can position insert
    let sel = window.getSelection();
    let text = div.textContent;
    let before = Math.min(sel.focusOffset, sel.anchorOffset);
    let after = Math.max(sel.focusOffset, sel.anchorOffset);
    //ensure string ends with \n so it displays properly
    let afterStr = text.substring(after);
    if (afterStr == "") afterStr = "\n";
    //insert content
    div.textContent = text.substring(0, before) + txt + afterStr;
    //restore cursor at correct position
    sel.removeAllRanges();
    let range = document.createRange();
    //childNodes[0] should be all the text
    range.setStart(div.childNodes[0], before + txt.length);
    range.setEnd(div.childNodes[0], before + txt.length);
    sel.addRange(range);
}

https://jsfiddle.net/1te5hwv0/


4
投票

可悲的是,你不能。正如这个 answer 指出 spec 仅指定

true
false
inherit
作为有效参数。这个主题似乎已经被讨论过,但如果我没记错的话,只有 Webkit 实现了对
plaintext-only
的支持。


0
投票

你可以

  1. paste
    事件监听器附加到元素
  2. 防止默认事件(粘贴任何内容)
  3. 尝试在剪贴板中查找纯文本
  4. 如果找到任何文本 -> 模拟仅粘贴纯文本

这将阻止图像粘贴或粘贴带有格式的文本

yourEditableElement.addEventListener('paste', (event) => {
  event.preventDefault();
  const text = event.clipboardData?.getData('text/plain');
  const selectedRange = window.getSelection()?.getRangeAt(0);
  if (!selectedRange || !text) {
    return;
  }

  selectedRange.deleteContents();
  selectedRange.insertNode(document.createTextNode(text));
  selectedRange.setStart(selectedRange.endContainer, selectedRange.endOffset);
});
© www.soinside.com 2019 - 2024. All rights reserved.