JS两种复制到剪贴板的方法

两种复制到剪贴板的方法

方法一:navigator.clipboard.writeText()(现代 Clipboard API)

原理

通过浏览器提供的异步 Clipboard API 实现,基于 Promise 操作剪贴板。

特点

  • 异步操作不阻塞主线程
  • 需要 HTTPS 或 localhost 安全上下文
  • API 简洁现代,代码量少
  • 必须在用户交互事件中触发

代码实现

javascript 复制代码
// Promise 写法
navigator.clipboard.writeText('要复制的文本')
  .then(() => console.log('复制成功'))
  .catch(err => console.error('复制失败:', err))

// async/await 写法
async function copyText(text) {
  try {
    await navigator.clipboard.writeText(text)
    console.log('复制成功')
  } catch (err) {
    console.error('复制失败:', err)
  }
}

浏览器支持

Chrome 66+、Firefox 63+、Safari 13.1+、Edge 79+

方法二:execCommand(传统实现)

原理

通过创建临时 <textarea> 元素,使用已废弃但广泛兼容的 document.execCommand('copy') 实现。

实现流程

  1. 创建隐藏的文本域元素
  2. 设置文本内容并添加到 DOM
  3. 选中文本内容
  4. 执行复制命令
  5. 清理 DOM 并恢复焦点

代码实现

javascript 复制代码
function copyTextToClipboard(text) {
  // 1. 创建临时 textarea 元素
  const element = document.createElement('textarea')
  const previouslyFocusedElement = document.activeElement

  // 2. 设置文本内容
  element.value = text
  element.setAttribute('readonly', '')
  
  // 3. 隐藏元素(不显示在页面上)
  element.style.contain = 'strict'
  element.style.position = 'absolute'
  element.style.left = '-9999px'
  element.style.fontSize = '12pt' // 防止 iOS 缩放

  // 4. 保存当前选择状态
  const selection = document.getSelection()
  const originalRange = selection.rangeCount > 0 && selection.getRangeAt(0)

  // 5. 添加到 DOM 并选中
  document.body.append(element)
  element.select()
  element.selectionStart = 0
  element.selectionEnd = text.length

  // 6. 执行复制命令
  let isSuccess = false
  try {
    isSuccess = document.execCommand('copy')
  } catch (err) {
    console.error('复制失败:', err)
  }

  // 7. 清理:移除元素,恢复选择状态和焦点
  element.remove()
  if (originalRange) {
    selection.removeAllRanges()
    selection.addRange(originalRange)
  }
  if (previouslyFocusedElement) {
    previouslyFocusedElement.focus()
  }

  return isSuccess
}

特点

  • 同步执行立即返回结果
  • 兼容 IE 等老旧浏览器
  • 实现复杂度较高
  • 已被现代标准标记为废弃
渐进增强策略

推荐实现方案

javascript 复制代码
function safeCopyText(text) {
  if (navigator.clipboard?.writeText) {
    return navigator.clipboard.writeText(text)
      .catch(() => copyTextToClipboard(text))
  }
  return copyTextToClipboard(text)
}

优势

  • 现代浏览器优先使用标准 API
  • 自动降级保证兼容性
  • 统一的错误处理机制

注意事项

  • 所有复制操作必须由用户交互触发
  • 建议添加成功/失败状态提示
  • 测试需覆盖不同浏览器环境
相关推荐
前端Hardy17 分钟前
前端必看!LocalStorage这么用,再也不踩坑(多框架通用,直接复制)
前端·javascript·面试
前端Hardy17 分钟前
前端必看!前端路由守卫这么写,再也不担心权限混乱(Vue/React通用)
前端·javascript·面试
Lee川38 分钟前
从零构建现代化登录界面:React + Tailwind CSS 前端工程实践
前端·react.js
Awu122739 分钟前
⚡精通 Claude 第 1 课:掌握 Slash Commands
前端·人工智能·ai编程
竹林81839 分钟前
从ethers.js迁移到Viem:我在重构DeFi前端时踩过的那些坑
前端·javascript
码云之上44 分钟前
上下文工程实战:解决多轮对话中的"上下文腐烂"问题
前端·node.js·agent
小小弯_Shelby1 小时前
webpack优化:Vue配置compression-webpack-plugin实现gzip压缩
前端·vue.js·webpack
小村儿1 小时前
连载04-CLAUDE.md ---一起吃透 Claude Code,告别 AI coding 迷茫
前端·后端·ai编程
攀登的牵牛花1 小时前
我把 Gemma4:26b 装进 M1 Pro 后,才看清 AI 编程最贵的不是模型费,而是工作流
前端·agent
前端郭德纲1 小时前
JavaScript Object.freeze() 详解
开发语言·javascript·ecmascript