使用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("当前设备不支持本插件");
}
}
以上就是前端复制的简单实现,方便后续再用到的时候,快速回忆。当然,文章如有不足之处,请童鞋们留言指出,感谢!