import $ from 'jquery'; // 1. 全局单例事件绑定(事件委托:性能拉满) $(document).on('click', '.js-copy', function() { // oCurrentBtn: 当前被点击的那个按钮对象 (Object) var oCurrentBtn = $(this); // sTargetText: 精准获取当前按钮上绑定的文本 (String) var sTargetText = oCurrentBtn.data('text'); // 如果没数据,直接拦截,防止复制空字符串 if (!sTargetText) { fnShowToast(oCurrentBtn, '无复制内容'); return; } // 执行核心复制逻辑 if (navigator.clipboard) { navigator.clipboard.writeText(sTargetText) .then(function() { fnShowToast(oCurrentBtn, '复制成功'); }) .catch(function(oError) { console.error('Clipboard API 失败,尝试兜底: ', oError); fnFallbackCopy(sTargetText, oCurrentBtn); }); } else { // 走兜底方案,并把当前按钮对象传进去 fnFallbackCopy(sTargetText, oCurrentBtn); } }); /** * 2. 兜底复制方法(去除了所有 alert,全部改为局部提示) * @param {string} sText * @param {object} oElement jQuery对象 */ function fnFallbackCopy(sText, oElement) { // oTextArea: 临时文本框对象 (Object) var oTextArea = document.createElement("textarea"); oTextArea.value = sText; // 样式隐形 oTextArea.style.position = "fixed"; oTextArea.style.top = "0"; oTextArea.style.left = "0"; oTextArea.style.opacity = "0"; document.body.appendChild(oTextArea); oTextArea.focus(); oTextArea.select(); try { // 执行老版复制指令 var sSuccess = document.execCommand('copy'); if (sSuccess) { fnShowToast(oElement, '复制成功'); } else { fnShowToast(oElement, '复制失败'); } } catch (oErr) { console.error('ExecCommand 彻底崩了: ', oErr); fnShowToast(oElement, '复制出错'); } // 及时销毁 DOM 节点,防止内存泄漏 document.body.removeChild(oTextArea); } /** * 3. 优雅的局部提示组件(高内聚,职责单一) * @param {object} oElement jQuery对象 * @param {string} sMsg 提示文字 */ function fnShowToast(oElement, sMsg) { if (oElement.prop('disabled')) { return; } sMsg = ""+sMsg+""; var sOriginalText = oElement.html(); // 改变文字并禁用按钮,防止二次点击带来连续 DOM 操作 oElement.html(sMsg).prop('disabled', true); // 1.5秒后恢复原状 setTimeout(function() { oElement.html(sOriginalText).prop('disabled', false); }, 1500); }