在 React 中使用 document.execCommand 将文本从 div 复制到剪贴板

IT技术 javascript reactjs use-ref
2021-05-16 03:10:40

我试图div在 URL 缩短后从 a 复制文本

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

类型错误: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>
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);
      }
    });
}

关于使用剪贴板 API 的注意事项

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

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

当页面位于活动选项卡中时,剪贴板写入权限会自动授予页面。必须请求剪贴板读取权限,您可以通过尝试从剪贴板读取数据来实现。

剪贴板 API(剪贴板写入权限)目前不受 Firefox 支持,但受 Chrome / Chromium 支持


或者,要使用Document.execCommand,您应该将 转换divinputtextarea(可以选择)并使用 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文本复制到剪贴板,如果你仍然想使用div