去除外部格式,但在 <pre> 元素输入上保留缩进和回车 returns

Strip external formatting but keep indentation and carriage returns on <pre> element input

我正在使用以下内容:

<style>
        pre {
            outline:none;
            font-family : monospace;
            white-space : pre;
            background-color : rgb(19, 22, 27);
            color            : #98d8e7;    
        }
        </style>
        <body>  
            <pre contenteditible="true"></pre>
        </body>

在 Chrome 中,我可以选择“粘贴”(不需要的结果)或“粘贴并匹配样式”(需要的结果),但在其他浏览器中只提供“粘贴”。

常规的“粘贴”会保留我不想要的原始内容格式,例如文本颜色和背景颜色。这对我的用例造成了不良结果。

我想做的是始终强制粘贴以匹配 <pre> 元素的样式。

我的一个想法是拦截粘贴的文本,将其传递给不可见的 textarea 元素,然后获取该值。但这似乎是(至少在我看来)应该非常简单的事情的额外工作。但我不确定如何完成它。

我愿意接受 javascript 或 css 解决方案。什么都行,真的。

抱歉,如果我在这里说的很明显——我知道这并不能完全解决你的问题——但你可以用 paste event 做一些事情,你可以在其中获取粘贴事件的数据text 并将元素的 innerHTML 设置为那个。

此方法可能无法按照您预期的方式保留白色 space。下面的框架实现替换了整个元素的内容,但是如果你走这条路,你可以用 getSelection 来解决这个问题:

function onPaste (e) {
  e.preventDefault(); // stop the paste
  const t = e.clipboardData.getData("text"); // grab the pasted content as plain text
  e.target.innerHTML = t; // set the element's innerHTML to the plain text
}

const p = document.getElementById('test');
p.addEventListener('paste', onPaste);
pre {
  min-height: 200px;
  outline: none;
  font-family: monospace;
  white-space: pre;
  background-color: rgb(19, 22, 27);
  color: #98d8e7;
}
<pre id="test" contenteditable></pre>

另一种类似的可能性是让粘贴通过,然后立即抓取元素的内容并删除所有格式。这似乎是一种更令人生畏的方法,但它会让您能够进行更多的手术清理。

function onPaste (e) {
  // setTimeout to wait for the paste to complete
  setTimeout(() => {
    // do something with p.innerHTML or p.innerText;
    console.log(e.target.innerHTML);
  }, 0);
}