JavaScript实现一个复制函数,兼容旧浏览器
这是一个完整的复制函数实现,先尝试使用现代的 Clipboard API,如果不成功则回退到传统的 execCommand 方法:
function copyToClipboard(text) {// 如果浏览器支持 Clipboard APIif (navigator.clipboard && window.isSecureContext) {return navigator.clipboard.writeText(text).then(() => {console.log('复制成功 (Clipboard API)');return true;}).catch(err => {console.warn('Clipboard API 复制失败,使用备用方法:', err);return execCopy(text);});} else {// 回退到 execCommand 方法return Promise.resolve(execCopy(text));}
}function execCopy(text) {return new Promise((resolve, reject) => {try {// 创建一个临时的 textarea 元素const textArea = document.createElement('textarea');textArea.value = text;// 设置样式使其不可见textArea.style.position = 'fixed';textArea.style.top = '0';textArea.style.left = '0';textArea.style.opacity = '0';textArea.style.pointerEvents = 'none';textArea.style.zIndex = '-1';document.body.appendChild(textArea);// 选中文本textArea.select();textArea.setSelectionRange(0, 99999); // 对于移动设备// 执行复制命令const successful = document.execCommand('copy');document.body.removeChild(textArea);if (successful) {console.log('复制成功 (execCommand)');resolve(true);} else {reject(new Error('execCommand 复制失败'));}} catch (err) {reject(err);}});
}// 使用示例
copyToClipboard('要复制的文本').then(success => {if (success) {console.log('复制成功!');// 可以在这里添加成功提示}}).catch(err => {console.error('复制失败:', err);// 可以在这里添加失败提示});// 或者使用 async/await
async function handleCopy() {try {const success = await copyToClipboard('要复制的文本');if (success) {console.log('复制成功!');}} catch (err) {console.error('复制失败:', err);}
}
这个实现的特点:
-
优先使用 Clipboard API:更现代、更安全的方法
-
自动回退机制:当 Clipboard API 失败或不支持时,自动使用
execCommand -
Promise 接口:统一的异步处理
-
完整的错误处理:捕获各种可能的错误
-
样式处理:临时元素不会影响页面布局
-
移动设备支持:使用
setSelectionRange确保在移动设备上也能正常工作
使用注意事项:
-
Clipboard API 需要在安全上下文(HTTPS 或 localhost)中工作
-
某些浏览器可能需要用户手势(如点击事件)才能执行复制操作
-
在用户交互事件(如点击)中调用此函数会有更高的成功率
简化版本(如果不需要详细的错误处理):
async function copyText(text) {try {if (navigator.clipboard && window.isSecureContext) {await navigator.clipboard.writeText(text);return true;} else {const textArea = document.createElement('textarea');textArea.value = text;textArea.style.cssText = 'position:fixed;top:0;left:0;opacity:0;';document.body.appendChild(textArea);textArea.select();const result = document.execCommand('copy');document.body.removeChild(textArea);return result;}} catch (err) {console.error('复制失败:', err);return false;}
}// 使用
copyText('要复制的文本').then(success => {console.log(success ? '复制成功' : '复制失败');
});
参考:https://www.ecjson.com/article/173.html
