如何防止特定元素的文本被复制到剪贴板?

3

在有人建议之前:不,user-select 不是正确的答案。

Daniel O'Connor 的 纯CSS方法 接近于解决问题,但由于 "可访问性问题" 我无法在我的用例中使用它。

我需要一种更好的方法来做同样的事情。我想不出如何实现;我认为没有一种可靠的跨浏览器兼容的方式来使用 JavaScript 将某些内容复制到剪贴板上。所以我认为只有 HTML 和 CSS 的解决方案。

编辑

我说 "我认为没有一种可靠的跨浏览器兼容的方式来使用 JavaScript 将某些内容复制到剪贴板上" 是因为其中一个解决方案可能是捕获复制事件(如果每个地方都支持的话)。但我刚意识到,即使 "有一种可靠的跨浏览器兼容的方式来使用 JavaScript 将某些内容复制到剪贴板上",当用户在移动设备上复制文本时,这可能也行不通。请纠正我如果我错了。

编辑2

我不想以任何方式阻止人们复制文本。我没有试图阻止访问文本。这是不可能的,也是不鼓励的。我只是试图让从我的应用程序中复制 N 个元素文本的用户得到更好的体验,以便在剪贴板中不会包含无关紧要的东西(例如时间戳元素的文本等)。


你有哪些无障碍使用的顾虑? - Type-Style
1
你想要实现的目标根本不可能。接受现实,继续前行。 - Marco Bonelli
@AdamLynch我不明白为什么你要在任何情况下否认用户复制内容的权利。仅仅用户的浏览器下载页面这个事实就意味着整个内容已经被“窃取”了,而你无法再加以控制。 - Marco Bonelli
@MarcoBonelli 哎呀,看看我最新的编辑。 - Adam Lynch
1
是的,@MoshMage,但它是否是重复问题取决于问题本身,而不是答案或评论。好的,很酷。 - Adam Lynch
显示剩余5条评论
2个回答

4

新答案

你希望在用户选择和复制文本时自动省略某些部分。

我知道两种解决方案:

  1. 将文本放在不同的父元素中
  2. 在用户开始选择时隐藏不需要的元素

解决方案#1通常用于带有行号的源代码。通过巧妙地应用CSS,可以垂直对齐两个DIV,以便每个行号似乎在正确行的源代码左侧(实际上在不同的DIV中)。

这样,您可以在源代码中拖动选择而不获取任何行号。这对可以在垂直/水平对齐的框中显示的信息非常有效,或者换句话说,如果您可以将事物放入不同的表格单元格中。

解决方案#2响应第一次鼠标单击,并将display:none应用于具有特定类别(例如omit-during-copy)的元素。

这种方法的优点是用户可以看到他们正在复制的内容(即不需要的信息正在消失)。

缺点是如何/何时恢复状态。

这种方法的变体是使用绝对定位使元素出现在某个位置。如果您必须将该技术应用于像aHIDEb这样的事物,那么这很快就会变得乏味-您必须在ab之间放置足够的空格以显示HIDE,然后将HIDE像素完美地放置在间隙中。不是不可能,但我建议先重新排列信息。

旧答案

有两种方法可以防止用户从HTML页面复制文本:

  1. 不要显示它
  2. 使用密码字段

让我解释一下:在页面本身中,您可以尝试使用JavaScript尝试的一小部分内容。如果您吞下Ctrl+C,则人们将使用鼠标。如果您在页面中吞咽鼠标按钮,则他们将使用菜单栏。如果您禁用浏览器的菜单栏,则人们将停用“允许JavaScript隐藏菜单栏”选项。

如果您使用密码字段,则人们将使用JavaScript控制台或“显示源代码”,或者他们将使用诸如Tampermonkey之类的工具来摆脱您的烦人干扰。

您可以尝试显示带有文本的图像。然后人们将使用OCR。因此,即使您使用基于Flash的HTML查看器替换整个页面,人们仍然可以复制文本。但是这会让他们非常生气。

个人笔记:我倾向于仅短暂地访问尝试此类事情的页面。我往往长时间记住这样的网站,并带有非常负面的情绪。因此,如果我是你,我只会尝试将人们从我的网站上赶走。


抱歉,我认为这不是我需要的。我已经对问题进行了第二次编辑以澄清。 - Adam Lynch
1
更好的问题标题应为:“防止某些元素被复制到剪贴板”,在问题描述中,“我希望让人们从我的页面上复制一些信息更加舒适。这些信息包含不需要的部分,如时间戳、行号等。” - Aaron Digulla
当你说“这没有任何作用 - 已经标记的元素已经是不可选择的”时,我不太明白你的意思。 - Adam Lynch
在我的情况下,无论如何都无法选择文本。 - Adam Lynch
啊,好的@Aaron,你是说这可能是一个意外,因为可能不支持用户选择。好的。 - Adam Lynch
显示剩余6条评论

4

如果有人仍在寻找一种方法来防止复制不重要的元素(如行号),答案是使用伪元素:

.code {
  white-space: pre;
  font-family: monospace;
  padding-left: 40px;
}
.line-number {
  position: absolute;
  left: 0;
  width: 38px;
  color: #888;
  text-align: right;
}
.line-number::before {
  content: attr(data-line-number);
}
<div class="code">
<span class="line-number" data-line-number="1"></span>const greet = () => {
<span class="line-number" data-line-number="2"></span>  console.log("Hello World!");
<span class="line-number" data-line-number="3"></span>};
</div>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接