当前位置: 首页 > news >正文

【navigator.clipboard】复制链接弹出详情信息(模拟电商app)、页面中粘贴图片、复制文本自动添加版权信息

文章目录

    • 复制链接弹出详情信息
    • 页面中粘贴图片
    • 复制文本自动添加版权信息
    • 代码

参考:淘宝、京东复制好友链接弹出商品详情是如何实现的最近接到了一个需求很有意思,类似于我们经常在逛购物平台中,选择一个物品分享 -掘金

逛博客发现一个有趣的功能,加强了对navigator.clipboard的理解,于是实现并记录一下。

复制链接弹出详情信息

复制链接到电商平台,会自动弹出商品详情信息。这里用前端技术栈实现一下。

思路:监听切回页面,查看剪切板第一个内容,如果是对应文案,则弹出一个弹窗。

切回页面:监听页面的visibilitychange事件,当document.visibilityState === 'visible'时,说明切回页面。(如果在客户端webview中,应该是onResume事件。不过与本博客内容无关,不展开)

读剪切板

  • navigator.clipboard要在安全的上下文中使用,所以要判断兼容性
  • setTimeout是为了解决本地开发环境的报错:document is not focused,详情查看javascript - DOMException on calling navigator.clipboard.readText() - Stack Overflow
  • document.execCommand也可以实现复制粘贴等需求,且没有上述问题。但是此API已被声明弃用。权衡之下这里选择使用navigator.clipboard。读者可以自行选择。详情查看:剪贴板操作 Clipboard API 教程 - 阮一峰的网络日志
if (window.isSecureContext && navigator.clipboard) {// setTimeout为了解决报错:https://stackoverflow.com/questions/56306153/domexception-on-calling-navigator-clipboard-readtext// document.execCommand 没有这个问题,但是已被声明弃用。权衡之下选择使用navigator.clipboardsetTimeout(() => {navigator.clipboard.readText().then((res) => {text.value = resif (isMyBlog(text.value)) {// 弹出一个弹窗dialogVisible.value = true}})}, 1000)} else {ElMessage.error('不支持剪切板navigator.clipboard')}

若剪切板的第一条是目标内容,则弹出弹窗:这里我将判断是否是我的博客。

const isMyBlog = (str: string) => {if (str.includes('/blog.csdn.net/karshey')) return truereturn false
}const handleVisibilityChange = () => {if (document.visibilityState === 'visible') {if (window.isSecureContext && navigator.clipboard) {// setTimeout为了解决报错:https://stackoverflow.com/questions/56306153/domexception-on-calling-navigator-clipboard-readtext// document.execCommand 没有这个问题,但是已被声明弃用。权衡之下选择使用navigator.clipboardsetTimeout(() => {navigator.clipboard.readText().then((res) => {text.value = resif (isMyBlog(text.value)) {dialogVisible.value = true}})}, 1000)} else {ElMessage.error('不支持剪切板navigator.clipboard')}}
}

页面中粘贴图片

在页面中粘贴图片,然后图片显示在页面上。

监听页面的粘贴:读取剪切板中第一个,若它是图片类型,则把它渲染到页面上。

// 页面中粘贴图片
const handlePaste = () => {if (window.isSecureContext && navigator.clipboard) {const clipboardApi = navigator.clipboardsetTimeout(() => {clipboardApi.read().then((clipboard) => {const img = clipboard[0]if (img.types.includes('image/png'))img?.getType('image/png').then((blob) => {// 如果之前有链接,要先释放它,否则会有内存泄漏if (imgUrl.value.length) {URL.revokeObjectURL(imgUrl.value)}imgUrl.value = URL.createObjectURL(blob)})})}, 1000)}
}

效果:

在这里插入图片描述

在csdn、掘金等博客平台,检测到粘贴时会把此图片上传到cdn,拿到图片链接后渲染。我们这里直接创建一个本地的链接。注意,当链接不需要时(这里的场景是粘贴了新图片),要释放链接:

if (imgUrl.value.length) {URL.revokeObjectURL(imgUrl.value)
}

否则会造成内存泄漏。

复制文本自动添加版权信息

监听复制事件,将选中内容+版权信息 写入剪切板。

const handleCopy = (e: Event) => {// 阻止默认的复制行为e.preventDefault()const selected = window.getSelection()?.toString()if (selected && window.isSecureContext && navigator.clipboard) {const copyWrite = '\n\n作者:karshey\n博客:https://blog.csdn.net/karshey'setTimeout(() => {const clipboardApi = navigator.clipboardclipboardApi.writeText(selected + copyWrite).then(() => {copyText.value = selected + copyWrite})}, 1000)}
}

代码

<template><div class="section"><h2>复制弹出详情</h2><div>当前剪切板:{{ text }}</div><div>如果复制了我的博客链接,则会弹出一个弹窗,模拟商品详情</div></div><div class="section"><h2>页面中粘贴图片</h2><img v-if="imgUrl.length" :src="imgUrl" alt="" height="200" /></div><div class="section"><h2>在此页面复制自动添加版权信息</h2><el-input v-model="copyText" disabled autosize type="textarea" :row="6"></el-input></div><el-dialog v-model="dialogVisible" title="Tips" width="500"><span><el-link :href="text" target="_blank">点击跳转到我的博客:{{ text }}</el-link></span><template #footer><div class="dialog-footer"><el-button type="primary" @click="dialogVisible = false"> 收到 </el-button></div></template></el-dialog>
</template><script lang="ts" setup>
import { onMounted, onUnmounted, ref } from 'vue'
import { ElMessage } from 'element-plus'
const text = ref('')
const dialogVisible = ref(false)
const imgUrl = ref('')
const copyText = ref('')onMounted(() => {document.addEventListener('visibilitychange', handleVisibilityChange)document.addEventListener('paste', handlePaste)document.addEventListener('copy', handleCopy)
})onUnmounted(() => {document.removeEventListener('visibilitychange', handleVisibilityChange)document.removeEventListener('paste', handlePaste)document.removeEventListener('copy', handleCopy)
})const isMyBlog = (str: string) => {if (str.includes('/blog.csdn.net/karshey')) return truereturn false
}const handleCopy = (e: Event) => {// 阻止默认的复制行为e.preventDefault()const selected = window.getSelection()?.toString()if (selected && window.isSecureContext && navigator.clipboard) {const copyWrite = '\n\n作者:karshey\n博客:https://blog.csdn.net/karshey'setTimeout(() => {const clipboardApi = navigator.clipboardclipboardApi.writeText(selected + copyWrite).then(() => {copyText.value = selected + copyWrite})}, 1000)}
}const handleVisibilityChange = () => {if (document.visibilityState === 'visible') {if (window.isSecureContext && navigator.clipboard) {// setTimeout为了解决报错:https://stackoverflow.com/questions/56306153/domexception-on-calling-navigator-clipboard-readtext// document.execCommand 没有这个问题,但是已被声明弃用。权衡之下选择使用navigator.clipboardsetTimeout(() => {navigator.clipboard.readText().then((res) => {text.value = resif (isMyBlog(text.value)) {dialogVisible.value = true}})}, 1000)} else {ElMessage.error('不支持剪切板navigator.clipboard')}}
}// 页面中粘贴图片
const handlePaste = () => {if (window.isSecureContext && navigator.clipboard) {const clipboardApi = navigator.clipboardsetTimeout(() => {clipboardApi.read().then((clipboard) => {const img = clipboard[0]if (img.types.includes('image/png'))img?.getType('image/png').then((blob) => {// 如果之前有链接,要先释放它,否则会有内存泄漏if (imgUrl.value.length) {URL.revokeObjectURL(imgUrl.value)}imgUrl.value = URL.createObjectURL(blob)})})}, 1000)}
}
</script><style lang="less" scoped>
.section {margin: 20px 0;
}
</style>

效果:

在这里插入图片描述

http://www.xdnf.cn/news/991963.html

相关文章:

  • CentOS7自带的yum依然无法联网到官方源
  • 自我推荐一下
  • 关于亚马逊WOOT折扣力度
  • 中国北方GNSS业务站网积雪深度数据集(GSnow-CHINA v1.0, 12h/24h, 2013-2...
  • 【烧脑算法】三指针的降维打击:三线并行锁定解题细节
  • 数据隐私是什么?如何做好数据隐私规范?
  • Nuttx之mm_extend
  • Python数据类型大全:整型、浮点、字符串与布尔值
  • Codeforces 1029 Div3(ABCDE)
  • Windows10下利用VS2019编译JpegLib
  • seo优化新利器:AI如何让内容批量生成与排名提升双管齐下?
  • Gremlin创建schema(包括实体和关系)
  • 【质数】埃氏筛法、线性筛法(欧拉筛法)
  • 【Linux系统编程】System V
  • Java锁机制对决:ReadWriteLock vs StampedLock
  • 从0到1落地一个RAG智能客服系统
  • ConcurrentHashMap详解:原理、实现与并发控制
  • 专访伦敦发展促进署CEO:在AI与黄仁勋之外,伦敦为何给泡泡玛特和比亚迪留了C位?
  • MySQL优化器
  • 3.3.1_2 检错编码(循环冗余校验码)
  • 【完整源码+数据集+部署教程】安检爆炸物检测系统源码和数据集:改进yolo11-REPVGGOREPA
  • 接口测试之文件上传
  • 【完整源码+数据集+部署教程】石材实例分割系统源码和数据集:改进yolo11-CA-HSFPN
  • 【Docker】快速入门与项目部署实战
  • Haclon例程1-<剃须刀片检测程序详解>
  • < 买了个麻烦 (二) 618 京东云--轻量服务器 > “可以为您申请全额退订呢。“ 工单记录:可以“全额退款“
  • linux引导过程与服务控制
  • nginx ./nginx -s reload 不生效
  • 2024-2030年中国轨道交通智能运维市场全景分析与战略前瞻
  • 永磁同步电机无速度算法--基于稳态卡尔曼滤波器SSEKF的滑模观测器