将文本复制到剪贴板:无法读取未定义的读取“writeText”的属性

问题描述 投票:0回答:4

我有一个按钮

当我点击复制时

copyImageLinkText({ mouseenter, mouseleave }, e) {
  this.showCopiedText = !this.showCopiedText
  navigator.clipboard.writeText(this.imageLink)

  clearTimeout(this._timerId)
  mouseenter(e)
  this._timerId = setTimeout(() => mouseleave(e), 1000)
},

这条线似乎在我的 MacBook Pro 上完美地本地工作

navigator.clipboard.writeText(this.imageLink)

当我构建并将其部署到我的开发服务器时,它工作。

类型错误:无法读取未定义的属性(读取“writeText”)

javascript vue.js vuejs2 vue-component copy-paste
4个回答
124
投票

使用

navigator.clipboard
需要安全来源。因此,如果您的开发环境通过 HTTP 提供服务,则剪贴板方法将不可用。

根据 MDN

Clipboard
文档

此功能仅在安全上下文 (HTTPS)、部分或所有支持的浏览器中可用。

也许您可以使用

window.isSecureContext
检查此方法是否可用,并相应地禁用“复制文本”按钮。


解决方法

最好的选择是在您的开发环境中使用 HTTPS。

但是既然您要求解决方法,这里有一个(非常hacky)工作方法。使用

Document.exec
命令(不再推荐),改用
ClipboardAPI

function unsecuredCopyToClipboard(text) {
  const textArea = document.createElement("textarea");
  textArea.value = text;
  document.body.appendChild(textArea);
  textArea.focus();
  textArea.select();
  try {
    document.execCommand('copy');
  } catch (err) {
    console.error('Unable to copy to clipboard', err);
  }
  document.body.removeChild(textArea);
}

使用方法

然后您可以检查是否为

!navigator.clipboard
并调用后备方法,否则继续正常的
navigator.clipboard.writeText(...)
功能。例如:

const unsecuredCopyToClipboard = (text) => { const textArea = document.createElement("textarea"); textArea.value=text; document.body.appendChild(textArea); textArea.focus();textArea.select(); try{document.execCommand('copy')}catch(err){console.error('Unable to copy to clipboard',err)}document.body.removeChild(textArea)};

/**
 * Copies the text passed as param to the system clipboard
 * Check if using HTTPS and navigator.clipboard is available
 * Then uses standard clipboard API, otherwise uses fallback
*/
const copyToClipboard = (content) => {
  if (window.isSecureContext && navigator.clipboard) {
    navigator.clipboard.writeText(content);
  } else {
    unsecuredCopyToClipboard(content);
  }
};
<button onClick="buttonPress()">➡️ Copy Message to Clipboard</button>

<script type="text/javascript"> const buttonPress = () => { copyToClipboard('Hello World!'); console.log('Clipboard updated 📥\nNow try pasting!'); }; </script>


2
投票

最好使用

async
并将代码放在
try catch
块中。

async copyCode() {
 try {
     await navigator.clipboard.writeText(this.input);
 } catch (e) {
     console.log(e);
 }
}


2
投票

对答案的一些补充,这对我很有用,使用

preventScroll
参数作为滚动函数的参数滚动,因为输入将被删除,您可能不需要滚动到它

 textArea.focus({preventScroll: true})

0
投票

抱歉粘贴了工作代码。 我正在使用 Jquery。 只要你愿意,你就可以用 JS 来做。 直到通过 https 视图才能工作..

$('.copy-email').click(function () {
    var email = $(this).data('email');
    writeClipboardText(email);
})

async function writeClipboardText(text) {
    try {
        await navigator.clipboard.writeText(text);
    } catch (error) {
        console.error(error.message);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.