



















vue3 项目,想要使用 js 实现点击触发跳转时,复制口令到剪贴板,注意这里,仅仅是复制到剪贴板。
注意事项:
click、touchstart)事件的同步代码中调用,如果在 setTimeout、promise、事件监听等 内或者后面都会导致执行失败/** * 复制文本到剪贴板 * 注意:必须在用户手势(如 click、touchstart)的同步调用链中执行,不能在异步回调中调用! * @param {string} text - 要复制的文本 * @returns {Promise<boolean>} - 是否复制成功 */ export function copyToClipboard(text) { return new Promise((resolve) => { // 优先使用现代 Clipboard API if (navigator.clipboard && typeof navigator.clipboard.writeText === 'function') { navigator.clipboard.writeText(text) .then(() => { console.log('[copyToClipboard] Clipboard API 复制成功') resolve(true) }) .catch((err) => { console.warn('[copyToClipboard] Clipboard API 失败:', err.message) const success = fallbackCopy(text) console.log('[copyToClipboard] 降级方案结果:', success) resolve(success) }) } else { console.log('[copyToClipboard] Clipboard API 不可用,使用降级方案') const success = fallbackCopy(text) console.log('[copyToClipboard] 降级方案结果:', success) resolve(success) } }) } /** * 降级复制方案(使用 textarea + execCommand,增强 iOS 兼容性) * @param {string} text - 要复制的文本 * @returns {boolean} - 是否复制成功 */ function fallbackCopy(text) { const textarea = document.createElement('textarea') textarea.value = text // 关键:设置 contentEditable 为 true,提高 iOS 选中兼容性 textarea.contentEditable = 'true' textarea.style.cssText = ` position: fixed; top: 0; left: 0; opacity: 0; pointer-events: none; width: 100px; height: 100px; z-index: -1; ` document.body.appendChild(textarea) // iOS 兼容性处理 const isIOS = /iPhone|iPad|iPod/i.test(navigator.userAgent) let success = false try { // 聚焦元素(iOS 需要) textarea.focus() if (isIOS) { const range = document.createRange() range.selectNodeContents(textarea) const selection = window.getSelection() selection.removeAllRanges() selection.addRange(range) textarea.setSelectionRange(0, text.length) } else { textarea.select() textarea.setSelectionRange(0, text.length) } success = document.execCommand('copy') console.log('[fallbackCopy] execCommand 复制结果:', success) } catch (err) { console.error('[fallbackCopy] execCommand 异常:', err) success = false } finally { document.body.removeChild(textarea) } return success } /** * 通过 scheme 打开 APP * @param {string} scheme - 完整的 scheme URL * @returns {void} */ export function openAppByScheme(scheme) { const isIOS = /iPhone|iPad|iPod/i.test(navigator.userAgent) if (isIOS) { // iOS 使用 iframe 方式,避免页面跳转 const iframe = document.createElement('iframe') iframe.style.display = 'none' iframe.src = scheme document.body.appendChild(iframe) setTimeout(() => { document.body.removeChild(iframe) }, 100) } else { // Android 直接跳转 window.location.href = scheme } } /** * 复制口令并打开 APP * @param {string} jumpCommand - 口令内容 * @param {string} schemePrefix - scheme 前缀,默认为抖音极速版 * @param {object} options - 配置选项 * @param {number} options.delay - 复制后延迟打开的时间(ms),默认 300ms * @returns {Promise<void>} */ export async function copyAndOpenApp(jumpCommand, schemePrefix = DEFAULT_SCHEME_PREFIX, options = {}) { const { delay = 300 } = options if (!jumpCommand) { console.warn('[copyAndOpenApp] jumpCommand 为空,跳过复制') return } // 复制口令 const copied = await copyToClipboard(jumpCommand) if (!copied) { console.warn('[copyAndOpenApp] 复制失败,但仍尝试打开 APP') } // 拼接 scheme 并打开 APP const scheme = `${schemePrefix}search?keyword=${encodeURIComponent(jumpCommand)}` // 延迟打开,确保复制操作完成 setTimeout(() => { openAppByScheme(scheme) }, delay) } /** * 复制口令到剪贴板 * @param {string} jumpCommand - 口令内容 */ export async function copyCommand(jumpCommand) { if (!jumpCommand) { console.warn('[copyCommand] jumpCommand 为空,跳过复制') return } // 复制口令 const copied = await copyToClipboard(jumpCommand) if (!copied) { console.warn('[copyCommand] 复制失败,但仍尝试打开 APP') } }
以上方法,如果仅复制口令,则使用 copyCommand,如果还要实现复制口令并打开,则使用 copyAndOpenApp。
常见报错:
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。