前端实现文本复制、禁用复制、解除复制功能

使用 navigator.clipboard 上的 writeText 方法进行复制,在本地运行是没有任何问题的,到了线上之后,由于测试环境是非安全域也即是 http,所以导致了浏览器出于安全考虑禁用非安全域的 navigator.clipboard,因此失效。

示例代码

js 复制代码
navigator.clipboard.writeText(formState.value.caseCode).then(() => {
  console.log('复制成功: ' + formState.value.caseCode);
}).catch(err => {
  console.error('复制失败: ', err);
});

Uncaught TypeError: Cannot read properties of undefined (reading 'writeText');

解决方法一

js 复制代码
/*
由于我们需要出于安全的考虑,那么我们就需要采用兼容的方法来复制文本。
例如当处于安全域时,采用一下方法
*/
navigator.clipboard
  .writeText(formState.value.caseCode)
  .then(() => {
    console.log('复制成功: ' + formState.value.caseCode);
  })
  .catch(err => {
    console.error('复制失败: ', err);
  });
/*
例如当处于非安全域时,采用一下方法
*/
let textArea = document.createElement('textarea');
textArea.value = formState.value.caseCode;
// 将文本框设置为不可见,避免影响用户体验
textArea.style.position = 'fixed';
textArea.style.top = '-9999px';
document.body.appendChild(textArea);

// 选择文本并复制
textArea.focus();
textArea.select();
const isSuccess = document.execCommand('copy');

// 移除临时的文本框
document.body.removeChild(textArea);
// 因此
// 复制案件编号
const copyToClipboard = () => {
  if (navigator.clipboard) {
    navigator.clipboard
      .writeText(formState.value.caseCode)
      .then(() => {
        // console.log('复制成功: ' + formState.value.caseCode);
      })
      .catch(err => {
        console.error('复制失败: ', err);
      });
  } else {
    let textArea = document.createElement('textarea');
    textArea.value = formState.value.caseCode;
    // 将文本框设置为不可见,避免影响用户体验
    textArea.style.position = 'fixed';
    textArea.style.top = '-9999px';
    document.body.appendChild(textArea);

    // 选择文本并复制
    textArea.focus();
    textArea.select();
    const isSuccess = document.execCommand('copy');

    // 移除临时的文本框
    document.body.removeChild(textArea);
  }
};

解决方法二

由于整体前端项目采用的时 vue3 框架,所以除了上述方法,还有更为简洁的方法,本项目也是采用的这个方案,即是使用插件

js 复制代码
// 首先下载插件
npm install vue-clipboard3;
// 然后引用
import clipboard3 from 'vue-clipboard3'
// 最后使用即可
const copyToClipboard = async () => {
  const { toClipboard } = clipboard3();
  await toClipboard(formState.value.caseCode);
  console.log('复制成功' + formState.value.caseCode);
}

因此,本次的线上 bug 也就解决了,那么,问题来了,文本如何实现禁止复制和解禁复制呢?

html 复制代码
// 那当然也很简单,我们可以去监听复制事件,只要监听到就阻止一下,代码如下:
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style>
      .box {
        margin: auto;
        width: 200px;
        display: flex;
        justify-content: space-between;
      }
    </style>
  </head>
  <body>
    <div class="box">
      <div class="copy">文字区域</div>
      <button>复制</button>
    </div>
  </body>
  <script>
    const isTure = false;
    copyEle.addEventListener('copy', e => {
      e.preventDefault();
      if (isTure) {
        // 可以复制 也即是解禁复制
        e.clipboardData.setData('text/plain', copyEle.innerHTML);
        alert('复制成功!');
      } else {
        // 无权限复制,也即是禁止复制
        alert('无权限!');
      }
    });
  </script>
</html>

当然上述代码只是针对某一个元素的复制和禁止复制,如果想要对项目所有文字的复制进行控制,只需要去监听 document 上的 copy 事件即可

html 复制代码
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>全局复制事件监听</title>
  </head>
  <body>
    <div class="box">
      <div class="copy">这是可以复制的文字区域</div>
      <button onclick="toggleCopyPermission()">切换复制权限</button>
    </div>

    <script>
      // 定义一个变量来控制是否允许复制
      let isTure = false;

      // 添加全局复制事件监听器
      document.addEventListener('copy', function (e) {
        e.preventDefault(); // 阻止默认的复制行为
        if (isTure) {
          // 允许复制,将选中的文本放入剪贴板
          const selectedText = window.getSelection().toString();
          e.clipboardData.setData('text/plain', selectedText);
          alert('复制成功!');
        } else {
          // 不允许复制,提示用户无权限
          alert('无权限!');
        }
      });

      // 切换复制权限的函数
      function toggleCopyPermission() {
        isTure = !isTure;
        alert(`复制权限已${isTure ? '开启' : '关闭'}`);
      }
    </script>
  </body>
</html>

以上就是几种前端实现文本复制、禁用复制和解禁复制功能。

相关推荐
雨雨雨雨雨别下啦23 分钟前
【从0开始学前端】vue3简介、核心代码、生命周期
前端·vue.js·vue
simon_934941 分钟前
受够了压缩和收费?我作为一个码农,手撸了一款无限容量、原图直出的瀑布流相册!
前端
e***87701 小时前
windows配置永久路由
android·前端·后端
Dorcas_FE2 小时前
【tips】动态el-form-item中校验的注意点
前端·javascript·vue.js
小小前端要继续努力2 小时前
前端新人怎么更快的融入工作
前端
四岁爱上了她2 小时前
input输入框焦点的获取和隐藏div,一个自定义的下拉选择
前端·javascript·vue.js
fouryears_234172 小时前
现代 Android 后台应用读取剪贴板最佳实践
android·前端·flutter·dart
boolean的主人3 小时前
mac电脑安装nvm
前端
用户1972959188913 小时前
WKWebView的重定向(objective_c)
前端·ios
烟袅3 小时前
5 分钟把 Coze 智能体嵌入网页:原生 JS + Vite 极简方案
前端·javascript·llm