核心思想
复制文本指令的核心就是 拿到当前想要复制的文本内容,放在一个
input输入框中,通过input元素的select属性选中文本内容,然后通过document.execCommand('copy')实现文本复制。
- 实现代码
function handleClick(text: string) { // 创建元素 if (!document.getElementById("copyTarget")) { const copyTarget = document.createElement("input"); copyTarget.setAttribute( "style", "position:fixed;top:0;left:0;opacity:0;z-index:-1000;" ); copyTarget.setAttribute("id", "copyTarget"); document.body.appendChild(copyTarget); } // 复制内容 const input: any = document.getElementById("copyTarget"); input.value = text; input.select(); document.execCommand("copy"); ElMessage({ message: "复制成功!", grouping: true, type: "success", }); }
document.execCommand
虽然一些浏览器仍然支持它,但也许已从相关的 web 标准中移除,也许正准备移除或出于兼容性而保留,不推荐使用。
- 语法
/** * aCommandName 命令的名称 * aShowDefaultUI 是否展示用户页面,默认false * aValueArgument 一些命令(例如 insertImage)需要额外的参数(insertImage 需要提供插入 image 的 url),默认为 null。 * bool:返回值为Boolean类型,如果是 `false` 则表示操作不被支持或未被启用。 **/ bool = document.execCommand(aCommandName, aShowDefaultUI, aValueArgument) - aCommandName
- copy 拷贝当前选中内容到剪贴板。
- cut 剪贴当前选中的文字并复制到剪贴板。
- paste 在光标位置粘贴剪贴板的内容
- ....查看更多
单击复制文本(v-copy)
- 添加单击事件
const copy: Directive = { mounted(el: any, binding: DirectiveBinding) { el.addEventListener("click", () => handleClick(el.innerText)); el.style.cursor = "copy"; }, }
双击复制文本(v-copy.dblclick)
- 区分单击指令,给指令追加修饰符
dblclick - 添加监听事件
dblclickconst copy: Directive = { mounted(el: any, binding: DirectiveBinding) { if (binding.modifiers.dblclick) { el.addEventListener("dblclick", () => handleClick(el.innerText)); el.style.cursor = "copy"; } }, }
点击图标复制文本(v-copy.icon)
- 区分指令,给指令追加修饰符
icon - 这里实现的思想是,给要复制文本的元素追加子元素(图标元素),点击的时候判断父元素中是否包含图标元素,包含则为其添加监听事件
const copy: Directive = { mounted(el: any, binding: DirectiveBinding) { if (binding.modifiers.dblclick) { el.addEventListener("dblclick", () => handleClick(el.innerText)); el.style.cursor = "copy"; } }, }
完整指令
/**
* v-copy
* 点击复制指令,可自行扩展至input
* 接收参数:function类型
*/
import type { Directive, DirectiveBinding } from "vue";
import { ElMessage } from "element-plus";
function handleClick(text: string) {
// 创建元素
if (!document.getElementById("copyTarget")) {
const copyTarget = document.createElement("input");
copyTarget.setAttribute(
"style",
"position:fixed;top:0;left:0;opacity:0;z-index:-1000;"
);
copyTarget.setAttribute("id", "copyTarget");
document.body.appendChild(copyTarget);
}
// 复制内容
const input: any = document.getElementById("copyTarget");
input.value = text;
input.select();
document.execCommand("copy");
ElMessage({
message: "复制成功!",
grouping: true,
type: "success",
});
}
const copy: Directive = {
mounted(el: any, binding: DirectiveBinding) {
// 双击触发复制
if (binding.modifiers.dblclick) {
el.addEventListener("dblclick", () => handleClick(el.innerText));
el.style.cursor = "copy";
}
// 点击icon触发复制
else if (binding.modifiers.icon) {
if (el.hasIcon) return;
const iconElement = document.createElement("i");
iconElement.setAttribute(
"class",
"iconfont icon-sishuxiangqing-huodongxiangqing"
);
iconElement.setAttribute("style", "margin-left:5px");
el.appendChild(iconElement);
el.hasIcon = true;
iconElement.addEventListener("click", () => handleClick(el.innerText));
iconElement.style.cursor = "copy";
}
// 单击触发复制
else {
el.addEventListener("click", () => handleClick(el.innerText));
el.style.cursor = "copy";
}
},
};
export default copy;