一键复制(js或插件)

本文介绍了如何使用JavaScript的`execCommand`API以及clipboard.js库来实现在前端复制文本的功能,包括原生实现和使用Vue组件库封装插件的方法,并提供了代码示例和注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用js原生的execCommand api实现:

function copyText(text) {
  // 数字没有 .length 不能执行selectText 需要转化成字符串
  const textString = text.toString();
  let input = document.querySelector('#copy-input');
  if (!input) {
    //没有该元素,动态创建一个
    input = document.createElement('input');
    input.id = "copy-input";
    input.readOnly = "readOnly";        // 防止ios聚焦触发键盘事件
    //给定样式,给用户一个无感的效果
    input.style.position = "absolute";
    input.style.left = "-1000px";
    input.style.zIndex = "-1000";
    document.body.appendChild(input)
  }
  input.value = textString;
  // ios必须先选中文字且不支持 input.select();
  selectText(input, 0, textString.length);
  console.log(document.execCommand('copy'), 'execCommand');
  if (document.execCommand('copy')) {
    document.execCommand('copy');
    alert('已复制到粘贴板');
  }
  input.blur();
  // input自带的select()方法在苹果端无法进行选择,所以需要自己去写一个类似的方法
  // 选择文本。createTextRange(setSelectionRange)是input方法
  function selectText(textbox, startIndex, stopIndex) {
    if (textbox.createTextRange) {//ie
      const range = textbox.createTextRange();
      range.collapse(true);
      range.moveStart('character', startIndex);//起始光标
      range.moveEnd('character', stopIndex - startIndex);//结束光标
      range.select();//不兼容苹果
    } else {//firefox/chrome
      textbox.setSelectionRange(startIndex, stopIndex);
      textbox.focus();
    }
  }
  window.scrollTo(0, 0) //保证页面不会滚动到最下面
};

使用插件 clipboard实现文本复制

可参考一:官方地址:clipboard.js — Copy to clipboard without Flash

可参考二:若依框架中的封装方法(使用了自定义指令,使用起来更加方便),路口:ruoyi-ui/src/directive/module/clipboard.js · 若依/RuoYi-Vue - Gitee.com 

1、安装插件

npm i clipboard

2.1 在html标签上直接使用(注,下面的方法,复制成功后,没有相应的页面反馈;但是实际上已经复制或剪切成功了):

<script setup lang='ts'>
import { ref } from "vue"
//引入插件
import ClipboardJS from "clipboard";
//实例化插件,需要指明要实现复制功能的标签元素,比如示例中的'.txt'元素,点击这个元素就可以实现复制的功能
new ClipboardJS(".txt")

//定义复制的内容,实际中按需替换
const copyTxt = ref<string>("你好,world!")
</script>

<template>
  <div>
    <!-- 直接使用data-clipboard-text方法 ,点击文本即可复制-->
    <div class="txt" :data-clipboard-text="copyTxt">
      {{ copyTxt }}
    </div>
    <!-- 使用data-clipboard-target方法 ,点击按钮后复制-->
    <hr />
    <p id="P">{{ copyTxt }}</p>
    <button class="txt" style="cursor: pointer;color:skyblue" data-clipboard-target="#P">复制</button>
    <hr />
    <!-- 通过data-clipboard-action指明是复制还是剪切 -->
    ’cut‘ 为剪切<br />
    <input :value="copyTxt" id="input" />
    <button class="txt" data-clipboard-action="cut" style="cursor: pointer;color:skyblue"
      data-clipboard-target="#input">剪切</button>
  </div>
</template>

2.2 封装该插件:

<script setup lang='ts'>
import { onUnmounted, onMounted, ref } from "vue";
const txt = ref<string>("今年除夕不放假!")
const btn = ref()
let clipboard: any;
onMounted(() => {
  //在该生命周期进行实例化,只能在这个周期内执行,确保btn这个DOM元素已经真实渲染出来
  clipboard = copyText(btn.value)
})
onUnmounted(() => {
  //当离开页面的时候,需要销毁这个实例,释放空间
  if (clipboard) {
    clipboard.destroy()
  }
})
</script>

<template>
  <div>
    <hr />
    <div>{{ txt }}</div>
    <!--data-copy 是自定义的,对应下面ts文件中的"trigger.dataset.copy"-->
    <button ref="btn" :data-copy="txt">复制</button>
  </div>
</template>

 封装的ts文件:

import ClipboardJS from "clipboard";

export function copyText(
  selector: string | Element | NodeListOf<Element>
): any {
  if (ClipboardJS.isSupported()) {
    //判断该环境或者设备是否支持clipboard.js;支持就实例
    const clipboard = new ClipboardJS(selector, {
      action: () => "copy", //默认为copy 复制,
      text: function (trigger: any) {
        console.dir(trigger); //结果:该元素,即 '<div>今年除夕不放假!</div>' 元素
        console.log(trigger.dataset.copy); //结果: 今年除夕不放假!
        return trigger.dataset.copy as string;
      },
    });

    //监听是否复制成功还是失败
    clipboard.on("success", (e) => {
      // alert("复制成功");
      console.log("复制成功");
      e.clearSelection();
    });
    clipboard.on("error", function (e) {
      console.error("Action:", e.action);
      console.error("Trigger:", e.trigger);
    });
    return clipboard; //当我们离开使用复制的页面的时候,需要清除这个实例,释放空间
  } else {
    alert("当前设备不支持本插件");
  }
}

以上就是前端复制的简单实现,方便后续再用到的时候,快速回忆。当然,文章如有不足之处,请童鞋们留言指出,感谢!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值