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

Posted

技术标签:

【中文标题】在 React 中使用 document.execCommand 将文本从 div 复制到剪贴板【英文标题】:Copy text from a div to clipboard using document.execCommand in React 【发布时间】: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>

【问题讨论】:

select 函数仅适用于 inputtextarea 元素。它不适用于div。见this answer。 【参考方案1】:

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

这里是如何使用 剪贴板 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 进行开发,可能是权限问题

以上是关于在 React 中使用 document.execCommand 将文本从 div 复制到剪贴板的主要内容,如果未能解决你的问题,请参考以下文章

react系列在React中使用Redux

是否可以在 React 中使用 Polymer?

无法在 React Native 应用程序中使用 React.memo

React-Redux:在 React 组件中使用动作创建器

[react] 在React中怎么使用字体图标?

[react] 举例说明在react中怎么使用样式