【问题标题】:Copy text from a div to clipboard using document.execCommand in React在 React 中使用 document.execCommand 将文本从 div 复制到剪贴板
【发布时间】:2021-04-09 19:09:58
【问题描述】:

我正在尝试在 URL 缩短后从 div 复制文本。

我在div 中放置了一个ref 值,它将呈现缩短的URL。但是,我收到错误:

TypeError: inputArea.input.select() 不是函数。

我不确定如何引用 div 中的文本。

import { useCallback, useEffect, useRef, useState } from "react";

const Shorten = () => {
        
    const [copySuccess, setCopySuccess] = useState('');
    const inputArea = useRef(null);
        
    function copyLink(e){
        inputArea.current.select();
        document.execCommand('copy');
        e.target.focus();
        setCopySuccess('Copied!');
    };
 
    {isPending && <div className="loading-text">Loading...</div>}
    {shortLink && <div ref={inputArea} className="shorten-text">{shortLink}</div>}
    <hr></hr>
    <div>
      <button className="shorten-it" onClick={copyLink} >Copy</button>
      {copySuccess}
    </div>
  </section>

【问题讨论】:

标签: javascript reactjs use-ref


【解决方案1】:

Document.execCommand 将被弃用,取而代之的是现代 Clipboard APIclipboard 交互。

这里是如何使用 剪贴板 API:

function updateClipboard(newClip) {
  navigator.clipboard.writeText(newClip).then(
    () => {
      setCopySuccess("Copied!");
    },
    () => {
      setCopySuccess("Copy failed!");
    }
  );
}

function copyLink() {
  navigator.permissions
    .query({ name: "clipboard-write" })
    .then((result) => {
      if (result.state === "granted" || result.state === "prompt") {
        updateClipboard(inputArea.current?.innerText);
      }
    });
}

关于使用Clipboard API的注意事项:

剪贴板 API 增加了更大的灵活性,因为您不限于将当前选择复制到剪贴板,而是可以直接指定要放入的信息剪贴板。

使用 API 要求您在 manifest.json 文件中拥有权限“clipboardRead”或“clipboardWrite”。

当页面处于活动标签中时,自动向页面授予剪贴板写入权限。必须请求剪贴板读取权限,您可以通过尝试从剪贴板读取数据来做到这一点。

Clipboard API (clipboard-write permission) is currently not supported by Firefox but supported by Chrome / Chromium


或者,要使用Document.execCommand,您应该将div 转换为inputtextarea(可以选择)并使用CSS 使其看起来像一个div:

function copyLink(e) {
  inputArea.current?.select();
  document.execCommand("copy");
  e.target.focus();
  setCopySuccess("Copied!");
}

// ...

{shortLink && (
  <input
    ref={inputArea}
    type="text"
    className="shorten-text"
    value={shortLink}
  />
)}

或者,如果您仍想使用div,请参阅How to copy text from a div to clipboard

【讨论】:

  • 谢谢我尝试了第一个解决方案,它给了我一个权限错误,所以我将 div 更新为一个输入字段并且它有效。我需要阅读有关剪贴板 API 工作原理的更多信息。
  • 我在 chrome 上测试了 Clipboard API。它工作并给了我 no 权限错误,因为写入权限是自动授予的。但我认为目前最好使用Document.execCommand,然后在更多浏览器支持时迁移到Clipboard API
  • 好的,我正在使用 Firefox 进行开发,可能是权限问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-22
  • 1970-01-01
  • 2019-11-23
相关资源
最近更新 更多