复制粘贴与网页

Avatar of Chris Coyier
Chris Coyier 发布

DigitalOcean 为您旅程的每个阶段提供云产品。立即开始使用 200 美元的免费额度!

您是否曾经尝试复制粘贴某些文本,却发现它令人沮丧、笨拙甚至不可能?我敢打赌您遇到过。这并非偶然。在网络上,您可以对其进行相当程度的控制。让我们将一些内容列出,供您思考。

并非真正的文本

这可能是最明显的问题,所以我们不必过多关注它。如果文本可以在网络上是“真正的文本”,请务必这样做。与文本图像相比,真实文本更易于访问、更易于索引且更有用。您可以选择它进行复制粘贴!

意外重叠

您是否曾经见过文本底部逐渐淡出的效果?这通常是通过在文本顶部叠加渐变图像来实现的。您可以透过它的一部分,但该元素仍然位于文本的顶部,这意味着鼠标交互发生在重叠处,而不是文本上。

由于重叠,我无法正确选择此处所需的文本。更糟糕的是,底部的链接无法点击。

此演示中,重叠是一个用渐变填充并定位在顶部的伪元素。值得庆幸的是,这在很大程度上是可以解决的问题。在重叠处使用 pointer-events: none; 将大有帮助。设置后,指针交互将完全忽略该元素。点击将直接穿过,就好像它不存在一样。

这很好,但 IE 10 不支持 pointer-events。如果您仍然想依赖它,Modernizr v3 有一个测试,因此您只有在知道 pointer-events 可用时才能应用叠加层。

或者,您可以像 我们在本文中介绍的那样,对各个行进行着色以使其看起来像淡出。

选择后的弹出窗口

有些网站在您选择某些文本后会做出一些非常大的假设。一个常见的情况是:哦,太好了,你好,你好,我看到你,你显然想在社交媒体上分享这段文字,让我来帮忙。 并非每个人都喜欢这样。除了自以为是和过于热心之外,它还会 妨碍 截屏。

Highlighter.js 是一个让这一切变得非常容易的库。

CSS 控制可选择性

实际上,CSS 存在一个专门用于控制文本可选择性的属性:user-select

.unselectable {
  -webkit-user-select: none;  /* Chrome all / Safari all */
  -moz-user-select: none;     /* Firefox all */
  -ms-user-select: none;      /* IE 10+ */
  user-select: none;          /* Likely future */       
}

除了几个 浏览器怪癖之外,设置了该属性的文本是不可选择的。在尝试设计围绕网站上文本可选择性的更好 UX 时,这非常有用。

在移动设备上,文本选择通常通过长按来完成,这会显示一些文本选择选项。您可以 阻止 该“弹出”(从而阻止文本选择),方法是使用

-webkit-touch-callout: default   /* displays the callout */
-webkit-touch-callout: none      /* disables the callout */

其他可见但无法复制的文本

您可以使用上面的 CSS 强制文本不可选择,但某些文本不会自动被选择

意外选择行号

有时您会在网站上遇到想要复制粘贴的代码块。粘贴后,您会发现行号也一起粘贴过来了。

这实际上有点令人惊讶,因为看起来您必须特别去做才能做到这一点。根据我们现在的了解,这些行号可以使用 CSS 阻止其被复制。或者代码可以被标记为列表以显示不会复制的数字。或者它可以使用不会复制的自定义计数器。或者在不会复制的行之前的伪元素(相关文章)。

因此,这只能发生在他们只是将一些文本放在行首的元素中,并且没有采取任何措施阻止其被复制的情况下。这可能是一个很容易解决的问题,我们可以鼓励任何违规者这样做。

使用 JavaScript 选择(所有)文本

表单元素通常用于此目的。如果您想提供一些专门用于复制粘贴的文本,通常将其放在 inputtextarea 中。

<textarea id="ta">a bunch of text</textarea>

然后,以编程方式选择该文本非常容易

var ta = document.getElementById("ta");
ta.focus();
ta.select();

您无法在 上执行此操作

或其他任何内容。此外,如果用户位于表单元素内,“选择全部”命令通常只会选择该元素范围内的文本,这是不错的预期行为。

如果您希望在点击文本时将其选中的行为,以下是一种非常简洁的 jQuery 方法

$('#ta').on("focus", function(e) {
  e.target.select();
  $(e.target).one('mouseup', function(e) {
    e.preventDefault();
  });
});

mouseup 中的这部分允许文本在 mouseup 事件后保持选中状态。通常,mouseup 会取消选择文本并激活光标。

我喜欢 这种方法,因为它也不会强制选择所有文本无论如何(人们 不喜欢),而只在初始焦点时选择。因此,在焦点之后,如果您想自己更改选择并仅复制文本的一部分,则可以这样做。

Google Fonts 就是一个违规者。如果您只想复制文本的一部分,那太糟糕了,您只能获取所有文本。

如果您不提供点击选择,这有时也会 让用户不满意,因此这是一个平衡。因此,我喜欢上面这种先聚焦到选择,然后让其保持原状的方法。

关于使用 JavaScript 选择文本,还有更多需要了解的内容,包括 范围选择 等,这 非常复杂,最好留到另一篇文章中介绍。

以编程方式复制到剪贴板

此功能 最近出现在 JavaScript 中。在撰写本文时,只有 Chrome 和 IE 支持。它是通过 document.execCommand('copy'); 实现的。

这里有一段我还没有完全了解的历史。我认为这在很大程度上是一个安全问题,这就是为什么它在 JavaScript 中是不可能的。更不用说一个品味问题了(谁想访问一个网站却发现他们的剪贴板被弄乱了?)。无论出于何种原因,它现在都可以使用了。

Matt Gaunt 提供了一些示例代码

请发送邮件至 [email protected]

var copyEmailBtn = document.querySelector('.js-emailcopybtn');  
copyEmailBtn.addEventListener('click', function(event) {  
  // Select the email link anchor text  
  var emailLink = document.querySelector('.js-emaillink');  
  var range = document.createRange();  
  range.selectNode(emailLink);  
  window.getSelection().addRange(range);  
    
  try {  
    // Now that we've selected the anchor text, execute the copy command  
    var successful = document.execCommand('copy');  
    var msg = successful ? 'successful' : 'unsuccessful';  
    console.log('Copy email command was ' + msg);  
  } catch(err) {  
    console.log('Oops, unable to copy');  
  }  
    
  // Remove the selections - NOTE: Should use   
  // removeRange(range) when it is supported  
  window.getSelection().removeAllRanges();  
});

以编程方式将文本复制到剪贴板一直以来都是一个愿望。我们过去不得不使用 Flash,通常是一个名为 ZeroClipboard 的库。这是 David Walsh 关于此主题的教程

如何复制粘贴并控制样式/格式

当你复制文本时,通常会连带复制其格式。

在 Mac 上,有一个**粘贴并匹配样式**命令,在你不想要原始格式的时候非常有用。比如粘贴到电子邮件中。Command-Shift-V 是这个命令的快捷键。

旁注:注意我这里用右键点击进行复制。一些用户会这么做。禁用右键点击(你可以在 JavaScript 中实现)会对这些用户造成阻碍,最好避免。

我通常更喜欢这种行为,所以我做了点事情,将它映射到 Command-V(覆盖正常的粘贴)。

如果你需要,你仍然可以通过菜单粘贴带有格式的文本。

剪贴板上的额外内容

你有没有从某个网站上选择了一些文本,却发现粘贴后,你的选择后面出现了一些额外的垃圾?阅读更多内容在 FART-KNUCKLE.BUSINESS!!!

不要那样做。

尴尬的保留大写

你可以使用 CSS 中的 text-transform: uppercase; 属性将文本大写。但是,它会导致不同浏览器在复制粘贴时出现相当大的(烦人)功能差异。

根据我快速测试的结果

  • Firefox 和 IE **尊重原始文本**(DOM 中的内容)。
  • Chrome、Safari、Opera 和 iOS **尊重 CSS** 的大写设置。

我更喜欢前者。

块级链接可能使复制更困难

在 HTML5 中,我们了解到现在可以将锚标签包裹在任何我们想要的内容周围。即使它们是内联元素,我们也可以将它们包裹在块级元素周围,而不用担心无效。但这并非没有后果的。

标题

这使得整个块级标题成为一个链接,无需任何 CSS 辅助,但它确实使标题有点难以复制。通过包裹该标记并使用 h3 &gt; a { display: block; } 可以使其更容易一些,假设 h3 上有一些填充,因为这样你就可以从填充开始选择并移动。

所以一方面点击区域更大,另一方面复制稍微困难一些(如果你习惯从右到左复制)。由你决定。

查看 CodePen 上 Chris Coyier (@chriscoyier) 的作品 块级标题有点难复制

有时块级结构本身会导致令人恼火的情况。就像这里,你试图选择一个电影标题,但鼠标偏离了一像素,你就得到了一堆在完全无关位置的奇怪文本。

这里的问题不算很大,因为我认为人们对此已经比较习惯了,知道如何退回并获取他们需要的内容。但值得考虑。即使像 Flexbox 排序这样的东西也会完全改变文本选择的行为,即使在视觉上看起来完全相同。

查看 CodePen 上 Chris Coyier (@chriscoyier) 的作品 flex 排序和选择

粘贴到控制台

经典的错误:在关于如何在终端执行操作的博文中,复制控制台命令开头的“$”。举手的人。只有我吗?该死。无论如何。有一个相当有趣的dotfile 东西可以在你这样做的时候警告你。

还有其他问题吗?

你对网络上的复制粘贴或选择是否有任何个人不满?