我使用的是ReactJS,当用户点击一个链接时,我想复制一些文本到剪贴板。

我使用Chrome 52,我不需要支持任何其他浏览器。

我不明白为什么这段代码没有导致数据被复制到剪贴板。(代码片段的来源是Reddit的一篇帖子)。

我做错了吗?谁能建议有一个“正确”的方法来实现复制到剪贴板使用reactjs?

copyToClipboard = (text) => {
  console.log('text', text)
  var textField = document.createElement('textarea')
  textField.innerText = text
  document.body.appendChild(textField)
  textField.select()
  document.execCommand('copy')
  textField.remove()
}

当前回答

对于那些试图从DIV而不是文本字段中进行选择的人,下面是代码。代码是不言自明的,但如果你想了解更多信息,请在这里评论:

     import React from 'react';
     ....

    //set ref to your div
          setRef = (ref) => {
            // debugger; //eslint-disable-line
            this.dialogRef = ref;
          };

          createMarkeup = content => ({
            __html: content,
          });

    //following function select and copy data to the clipboard from the selected Div. 
   //Please note that it is only tested in chrome but compatibility for other browsers can be easily done

          copyDataToClipboard = () => {
            try {
              const range = document.createRange();
              const selection = window.getSelection();
              range.selectNodeContents(this.dialogRef);
              selection.removeAllRanges();
              selection.addRange(range);
              document.execCommand('copy');
              this.showNotification('Macro copied successfully.', 'info');
              this.props.closeMacroWindow();
            } catch (err) {
              // console.log(err); //eslint-disable-line
              //alert('Macro copy failed.');
            }
          };

              render() {
                    return (
                        <div
                          id="macroDiv"
                          ref={(el) => {
                            this.dialogRef = el;
                          }}
                          // className={classes.paper}
                          dangerouslySetInnerHTML={this.createMarkeup(this.props.content)}
                        />
                    );
            }

其他回答

我个人认为没有必要为此建立一个图书馆。看看http://caniuse.com/#feat=clipboard,它现在得到了相当广泛的支持,但是你仍然可以做一些事情,比如检查当前客户端是否存在该功能,如果它不存在,就隐藏复制按钮。

import React from 'react';

class CopyExample extends React.Component {

  constructor(props) {
    super(props);

    this.state = { copySuccess: '' }
  }

  copyToClipboard = (e) => {
    this.textArea.select();
    document.execCommand('copy');
    // This is just personal preference.
    // I prefer to not show the whole text area selected.
    e.target.focus();
    this.setState({ copySuccess: 'Copied!' });
  };

  render() {
    return (
      <div>
        {
         /* Logical shortcut for only displaying the 
            button if the copy command exists */
         document.queryCommandSupported('copy') &&
          <div>
            <button onClick={this.copyToClipboard}>Copy</button> 
            {this.state.copySuccess}
          </div>
        }
        <form>
          <textarea
            ref={(textarea) => this.textArea = textarea}
            value='Some text to copy'
          />
        </form>
      </div>
    );
  }

}
    
export default CopyExample;

更新:在React 16.7.0-alpha.0中使用React hook重写

import React, { useRef, useState } from 'react';

export default function CopyExample() {

  const [copySuccess, setCopySuccess] = useState('');
  const textAreaRef = useRef(null);

  function copyToClipboard(e) {
    textAreaRef.current.select();
    document.execCommand('copy');
    // This is just personal preference.
    // I prefer to not show the whole text area selected.
    e.target.focus();
    setCopySuccess('Copied!');
  };

  return (
    <div>
      {
       /* Logical shortcut for only displaying the 
          button if the copy command exists */
       document.queryCommandSupported('copy') &&
        <div>
          <button onClick={copyToClipboard}>Copy</button> 
          {copySuccess}
        </div>
      }
      <form>
        <textarea
          ref={textAreaRef}
          value='Some text to copy'
        />
      </form>
    </div>
  );
}
make a componant as follows :- 

//react functional componant 

import React, { useState } from "react";

function CopyToClipboard(props) {
  const [copied, setCopied] = useState("copy");
  return (
    <div
      className="font-medium mr-4 text-green-700 cursor-pointer"
      onClick={() => {
        navigator.clipboard.writeText(props.text);
        setCopied("copied");
      }}>
      {copied}
    </div>
  );
}

export default CopyToClipboard;

//then use this componant anywhere

<CopyToClipboard text={"text you want to copy"}></CopyToClipboard>

//it will give a text saying "copy"`enter code here` and after clicking on that text, text provided with props will get copied
                    
                  

最简单的方法是使用react-copy-to-clipboard npm包。

您可以使用以下命令安装它

npm install --save react react-copy-to-clipboard

请按照以下方式使用它。

const App = React.createClass({
  getInitialState() {
    return {value: '', copied: false};
  },


  onChange({target: {value}}) {
    this.setState({value, copied: false});
  },


  onCopy() {
    this.setState({copied: true});
  },


  render() {
    return (
      <div>

          <input value={this.state.value} size={10} onChange={this.onChange} />

        <CopyToClipboard text={this.state.value} onCopy={this.onCopy}>
          <button>Copy</button>
        </CopyToClipboard>

                <div>
        {this.state.copied ? <span >Copied.</span> : null}
                </div>
        <br />

        <input type="text" />

      </div>
    );
  }
});

ReactDOM.render(<App />, document.getElementById('container'));

以下链接提供了详细的解释

https://www.npmjs.com/package/react-copy-to-clipboard

这是一把移动小提琴。

找到了最好的方法。我是说最快的方法:w3school

https://www.w3schools.com/howto/howto_js_copy_clipboard.asp

在react函数组件中。创建名为handleCopy的函数:

function handleCopy() {
  // get the input Element ID. Save the reference into copyText
  var copyText = document.getElementById("mail")
  // select() will select all data from this input field filled  
  copyText.select()
  copyText.setSelectionRange(0, 99999)
  // execCommand() works just fine except IE 8. as w3schools mention
  document.execCommand("copy")
  // alert the copied value from text input
  alert(`Email copied: ${copyText.value} `)
}

<>
              <input
                readOnly
                type="text"
                value="exemple@email.com"
                id="mail"
              />
              <button onClick={handleCopy}>Copy email</button>

</>

如果不使用React, w3schools也有一个很酷的方法来做到这一点,工具提示包括:https://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_copy_clipboard2

如果使用React,一个很酷的想法是:使用Toastify提醒消息。 https://github.com/fkhadra/react-toastify这是一个很容易使用的库。 安装后,你可以更改这一行:

 alert(`Email copied: ${copyText.value} `)

比如:

toast.success(`Email Copied: ${copyText.value} `)

如果你想使用它,不要忘记安装toastify。导入ToastContainer,同时也导入css:

import { ToastContainer, toast } from "react-toastify"
import "react-toastify/dist/ReactToastify.css"

并将烤面包的容器放入里面返回。

import React from "react"

import { ToastContainer, toast } from "react-toastify"
import "react-toastify/dist/ReactToastify.css"


export default function Exemple() {
  function handleCopy() {
    var copyText = document.getElementById("mail")
    copyText.select()
    copyText.setSelectionRange(0, 99999)
    document.execCommand("copy")
    toast.success(`Hi! Now you can: ctrl+v: ${copyText.value} `)
  }

  return (
    <>
      <ToastContainer />
      <Container>
                <span>E-mail</span>
              <input
                readOnly
                type="text"
                value="myemail@exemple.com"
                id="mail"
              />
              <button onClick={handleCopy}>Copy Email</button>
      </Container>
    </>
  )
}

这是另一个用例,如果你想复制当前的url到你的剪贴板:

定义一个方法

const copyToClipboard = e => {
  navigator.clipboard.writeText(window.location.toString())
}

调用那个方法

<button copyToClipboard={shareLink}>
   Click to copy current url to clipboard
</button>