
HTML
<template><div class="report_generate_wrap" id="parentElement"><div ref="textContainer" @mouseup="mouseUp" v-html="textContent"></div><div v-if="showCopyPopup" :style="copyPopupStyle" class="copy-popup"><p>已选中文本,点击复制:</p><button @click="copyText" style="margin-right: 10px">复制</button><button @click="hideCopyPopup">取消</button></div></div>
</template>
JS
data() {return {textContent: "这是一段示例文本,你可以尝试选中它。",showCopyPopup: false,selectedText: "",lastMousePosition: { x: 0, y: 0 },previousSelectedText: "",};},computed: {copyPopupStyle() {return {position: "absolute",left: `${this.lastMousePosition.x + 20}px`, // 假设弹窗距离鼠标右侧20pxtop: `${this.lastMousePosition.y}px`,transform: "translateY(-50%)", // 垂直居中};},
},mounted() {window.addEventListener("click", this.handleGlobalClick);
},beforeDestroy() {window.removeEventListener("click", this.handleGlobalClick);
},methods: {handleGlobalClick(event) {// 如果点击事件不是发生在textContainer元素内,则隐藏复制弹窗if (!this.$refs.textContainer.contains(event.target)) {this.showCopyPopup = false;}},mouseUp(event) {console.log("鼠标松开");this.updateMousePosition(event);const selection = window.getSelection();if (selection.rangeCount > 0) {const range = selection.getRangeAt(0);this.selectedText = range.toString().trim();// 检查当前选中的文本是否与之前选中的文本不同if (this.selectedText !== this.previousSelectedText) {if (this.selectedText !== "") {this.showCopyPopup = true;} else {this.showCopyPopup = false;}// 更新之前选中的文本this.previousSelectedText = this.selectedText;} else {// 如果相同,则不显示复制弹出框this.showCopyPopup = false;}} else {this.showCopyPopup = false;this.selectedText = "";this.previousSelectedText = ""; // 清除之前选中的文本}},updateMousePosition(event) {const parentElement = document.getElementById("parentElement");this.lastMousePosition = {x: event.clientX - parentElement.getBoundingClientRect().left,//鼠标相对于父元素的位置y: event.clientY,};},copyText() {const textarea = document.createElement("textarea");textarea.value = this.selectedText;document.body.appendChild(textarea);textarea.select();document.execCommand("copy");document.body.removeChild(textarea);this.hideCopyPopup();},hideCopyPopup() {this.showCopyPopup = false;},
}
CSS
<style scoped lang="less">
.copy-popup {background-color: white;border: 1px solid #ccc;padding: 10px;z-index: 1000;
}
</style>