在构建网站以允许用户在某些事件中从您的网站复制文本时,您可能遇到了这种情况。我在这里有一个类似的功能来复制代码片段。
让我们看看如何将相同的内容添加到您的网站以复制内容。
HTMLElement.select()以下是最简单的工作版本的代码。
- const copyText = str => {
- //Create new element
- const elm = document.createElement('textarea');
-
- //Fill the new element with text
- elm.value = str;
-
- //Append the new element
- document.body.appendChild(elm);
-
- //Select the content of the element
- elm.select();
-
- //Copy the content
- document.execCommand('copy');
-
- //Remove the element
- document.body.removeChild(elm);
- };
现在这是一个纯函数,它将复制事件上的内容,如 或 。你必须将文本传递给它进行复制。
它似乎工作正常,但存在一些问题。
1.我们添加到DOM中的元素将是可见的,这是一个糟糕的用户体验。
用户可能已经选择了HTML文档上的一些内容,这些内容将在此操作后刷新,因此我们必须恢复原始选择。
我们可以设置 样式,使其在 DOM 上不可见,但仍能够执行其工作。
- const copyText = str => {
- //Create new element
- const elm = document.createElement('textarea');
-
- //Fill the new element with text
- elm.value = str;
-
- //Hiding the appended element.
- elm.setAttribute('readonly', '');
- elm.style.position = 'absolute';
- elm.style.left = '-9999px';
-
- //Append the new element
- document.body.appendChild(elm);
-
- //Select the content of the element
- elm.select();
-
- //Copy the content
- document.execCommand('copy');
-
- //Remove the element
- document.body.removeChild(elm);
- };
用户可能已经在DOM上选择了某些内容,因此将其删除并不好。
幸运的是,我们可以使用一些新的javascript,如DocumentOrShadowRoot.getSelection(),Selection.rangeCount,Selection.getRangeAt(),Selection.removeAllRanges()和Selection.addRange()来保存和恢复原始文档选择。
- const copyText = str => {
- //Create new element
- const elm = document.createElement('textarea');
-
- //Fill the new element with text
- elm.value = str;
-
- //Hiding the appended element.
- elm.setAttribute('readonly', '');
- elm.style.position = 'absolute';
- elm.style.left = '-9999px';
-
- //Append the new element
- document.body.appendChild(elm);
-
- // Check if there is any content selected previously
- const selected =
- document.getSelection().rangeCount > 0
- ? document.getSelection().getRangeAt(0) // Store selection if found
- : false; // Mark as false to know no selection existed before
-
- // Select the <textarea> content
- el.select();
-
- // Copy - only works as a result of a user action (e.g. click events)
- document.execCommand('copy');
-
- // Remove the <textarea> element
- document.body.removeChild(el);
-
- // If a selection existed before copying
- if (selected) {
- document.getSelection().removeAllRanges(); // Unselect everything on the HTML document
- document.getSelection().addRange(selected); // Restore the original selection
- }
- };
如果您想通过直接单击或对其执行操作来将文本复制到javascript中的剪贴板,则还有另一种方法。
剪贴板 API 在对象上可用。navigator.clipboard
剪贴板 API 是相对较新的,并非所有浏览器都实现它。它适用于Chrome,现代Edge(基于chromium),Firefox和Opera。
我们可以检查它是否受支持。
- if (!navigator.clipboard) {
- // Clipboard API not available
- return
- }
您现在必须了解的一件事是,未经用户许可,您无法从剪贴板复制/粘贴。
如果您正在阅读或写入剪贴板,则权限会有所不同。如果您正在编写,您所需要的只是用户的意图:您需要将剪贴板操作放在对用户操作的响应中,例如单击。
假设我们有一个段落元素,我们想要复制其内容。
<p>Master DSA with Javascript</p>
当我们单击此文本时,我们希望将其复制到剪贴板上。因此,我们为其分配一个事件侦听器。
- document.querySelector('p').addEventListener('click', async event => {
- if (!navigator.clipboard) {
- // Clipboard API not available
- return;
- }
- });
然后,我们调用并将段落元素的文本复制到剪贴板。由于这是一个异步进程,我们将使用异步/等待。navigator.clipboard.writeText()
- document.querySelector('p').addEventListener('click', async event => {
- if (!navigator.clipboard) {
- // Clipboard API not available
- return;
- }
-
- //Get the paragraph text
- const text = event.target.innerText
- try {
- //Write it to the clipboard
- await navigator.clipboard.writeText(text);
-
- //Change text to notify user
- event.target.textContent = 'Copied to clipboard';
- } catch (err) {
- console.error('Failed to copy!', err);
- }
- })
在剪贴板上编写内容后,我们也可以从那里阅读它。
从剪贴板获取复制的内容。
<p>Master Full stack development with Javascript</p>
当我们单击此文本时,我们希望将其从我们复制的内容中更改。
- document.querySelector('p').addEventListener('click', async event => {
- if (!navigator.clipboard) {
- // Clipboard API not available
- return;
- }
- });
然后,我们调用并从剪贴板获取复制的文本。由于这是一个异步进程,我们将使用异步/等待。navigator.clipboard.readText()
- document.querySelector('p').addEventListener('click', async event => {
- if (!navigator.clipboard) {
- // Clipboard API not available
- return;
- }
- try {
- //Get the copied text
- const text = await navigator.clipboard.readText();
-
- //Pass it to the element.
- event.target.textContent = text;
- } catch (err) {
- console.error('Failed to copy!', err);
- }
- });