复制两个 <p> 会产生一个空行;复制 <h1> 元素不会

Copying two <p> produces a blank line; copying <h1> elements doesn't

提问人:Raman Sinclair 提问时间:8/4/2023 最后编辑:Raman Sinclair 更新时间:8/6/2023 访问量:98

问:

因此,如果我们选择并复制两个相邻的段落,然后将其粘贴到文本编辑器中,它们之间将有一个空行。如果我们做同样的事情,但对任何其他块元素,例如标题,则没有空行。为什么会发生这种情况,我怎样才能在其他块元素上实现这种行为?

代码(段落):

<p>first paragraph</p>
<p>second paragraph</p>

结果(段落):

> first paragraph
> 
> second paragraph

代码(其他元素):

<h3>first paragraph</h3>
<h3>second paragraph</h3>

结果(其他元素):

> first paragraph
> second paragraph

请注意,第二个结果中的行之间没有空行。

textarea {
  width: 30em;
  height: 10em;
}
<h3>Select and copy these four lines of text</h3>
<div>Paste into the textarea below</div>
<p>There is a blank line after the P element</p>
<h4>What causes this?</h4>
<textarea></textarea>

html css

评论

0赞 ralph.m 8/4/2023
这看起来更像是一个关于代码编辑器的问题,而不是关于 HTML/CSS 的问题。
0赞 Tim R 8/4/2023
我编辑了您的问题以包含可重复的片段
1赞 Keyboard Corporation 8/4/2023
p被视为块级元素,因此它将添加空格/换行符。如果不想使用新行,请将其属性从 block 设置为 inline。所以你可以在你的css中做。pp{ display: inline; }
1赞 t.niese 8/4/2023
@Newbee OP 想知道在选择块元素并将其复制到纯文本字段时,如何控制是否在块元素之后添加新行。
0赞 knittl 8/4/2023
你是在问元素是如何渲染的吗?我不认为我在关注。当我复制+粘贴 HTML 时,没有添加额外的行。当我复制+粘贴时,段落后没有空行(但在段落之前有一个空行,即在div之后)。

答:

4赞 t.niese 8/4/2023 #1

标准中没有任何内容指定如何将呈现的 DOM 中的选择转换为纯文本,因此这完全取决于您从中复制的应用程序和/或您“粘贴”的应用程序。

3.2.7 innerText 和 outerText 属性,它说:

  1. 如果 node 是元素,则在项的开头和结尾附加 2(所需的换行符计数)。p

但这仅在您使用 或 时才有意义;但是,如果渲染的 DOM 中的选择转换为纯文本,则不会考虑这一点,因为那里的 CSS 会影响间距或根本没有新行。.innerText.outerText

剪贴板可以保存您复制的数据的多个表示形式。

在“粘贴”时,应用程序将检查剪贴板以查找目标的最佳匹配表示(或用户选择插入的所需行为),并在必要时转换数据(使用自己的规则)

在 JavaScript 中,您可以在复制时覆盖剪贴板中存储的内容:

function copyListener(event) {
  event.clipboardData.setData("text/html", "here we have <strong>html</strong>");
  event.clipboardData.setData("text/plain", 'this is just plain text');
  event.preventDefault();

};

document.addEventListener("copy", copyListener, false);
.editor {
  width: 30em;
  height: 10em;
  border: 1px solid rgb(200, 200, 200)
}
<p>copy me</p>
<p>
  Paste as Plain:
</p>
<textarea class="editor"></textarea>
<p>
  Paste as HTML:
</p>
<div contenteditable class="editor">
</div>

因此,正如您在此处看到的,与“复制我”完全不同的内容保存在剪贴板中,具体取决于您是将其“粘贴”还是获取相应的数据。<textarea>contenteditable

如果您将其“粘贴”到其他应用程序中,也是如此(对于许多应用程序和操作系统)。如果您“正常”将其粘贴为 RTE,它将使用 HTML 版本,或者如果您选择“粘贴为纯文本”或“粘贴并匹配样式”,它将使用“文本/纯文本”。如果不存在“text/plain”,则由执行粘贴的应用程序决定如何设置其格式。

因此,如果你想为纯文本提供一致的东西,你可以按原样使用,然后用你自己转换的文本覆盖。htmltext/plain

function copyListener(event) {
  const range = window.getSelection().getRangeAt(0);
  const rangeContents = range.cloneContents();
  const wrapper =  document.createElement('div')
  wrapper.appendChild(rangeContents);

  // store the actual HTML for rich text editors
  event.clipboardData.setData("text/html", wrapper.innerHTML);

  // store some custome plain text
  event.clipboardData.setData("text/plain", 'my custom plain text');
  
  event.preventDefault();
};


document.addEventListener("copy", copyListener, false);
.editor {
  width: 30em;
  height: 10em;
  border: 1px solid rgb(200, 200, 200)
}
<h3>Select and copy these four lines of text</h3>
<div>Paste into the textarea below</div>
<p>There is a blank line after the P element</p>
<h4>What causes this?</h4>


<p>
  Paste as Plain:
</p>
<textarea class="editor"></textarea>
<p>
  Paste as HTML:
</p>
<div contenteditable class="editor">
</div>

评论

0赞 Raman Sinclair 8/5/2023
在 Chromium 上观察到此问题(在 Brave 浏览器中复制,在 VSCode 中粘贴)。我不得不调试 chromium 源代码才能弄清楚这一点,这让我得出了这个结论:github.com/chromium/chromium/blob/...。事实证明,这里的 Chromium 实际上依赖于 innerText/outerText 的标准:html.spec.whatwg.org/multipage/...
0赞 Raman Sinclair 8/5/2023
该标准内容如下:由于它是标准的一部分,我认为它不会被视为错误,但我真的不明白在那里插入双换行符的原因。有没有办法查看特定条款何时添加到标准中?我也认为在复制文本时依赖这个标准可能是不正确的,但也许我没有看到什么,chromium 代码库相当大......§ 3.2.7...8: If node is a p element, then append 2 (a required line break count) at the beginning and end of items.
0赞 t.niese 8/5/2023
@RamanSinclair 更新答案。只是关于,而不考虑 CSS。但是 HTML 描述的内容的呈现方式在很大程度上受到 CSS 的影响。因此,该标准需要描述如何 - 也考虑到CSS - 必须将所选文本转换为纯文本。§ 3.2.7innerTextouterText
0赞 Raman Sinclair 8/6/2023
是的,正如我所说,这个标准似乎与剪贴板操作无关,但看起来这就是 Chromium 在将富内容写入纯文本剪贴板缓冲区时所依赖的。如果我没看错的话,情况不一定如此。我将尝试提出 Chromium 项目的问题,让我们看看团队怎么说。同时,我会接受这个答案,因为它帮助我了解了该往哪个方向挖掘。
0赞 t.niese 8/9/2023
@RamanSinclair 如果您对此有了更多的了解并获得了更深入的知识,请随时写下自己的答案并接受该答案。