Telegram WebApp原生copy监听实现方案

原生 copy 监听实现方案

实现用户通过手机浏览器、Telegram 小程序、PC 浏览器等方式 使用系统原生复制操作 时,自动触发提示反馈(如弹窗、震动等),无需依赖复制按钮。


💡 灵感来源

此方案源自对 Hexo 博客主题(如 Butterfly、Fluid 等)实际行为的观察:

  • 用户长按选中文字 → 使用系统“复制”按钮 → 页面弹出复制成功提示。
  • 说明其复制提示并非绑定点击按钮,而是监听 copy 事件实现。

因此确认:可以监听用户触发的原生 copy 行为,并在监听中加入提示逻辑。


✅ 功能描述

  • ✅ 支持原生复制行为(长按 → 复制);
  • ✅ Telegram WebApp / iOS / Android 均可触发;
  • ✅ 支持带图标的提示框;
  • ✅ 可选配震动反馈;
  • ✅ 对无空格长串字符强制换行处理。

📦 实现代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
<script>
// Toast 弹窗函数
function showToast(msg) {
let el = document.getElementById('toast-msg');
if (!el) {
el = document.createElement('div');
el.id = 'toast-msg';
el.style.cssText = `
position: fixed;
bottom: 80px;
left: 50%;
transform: translateX(-50%);
background: rgba(0, 0, 0, 0.85);
color: #fff;
padding: 10px 16px;
border-radius: 10px;
z-index: 9999;
max-width: 90%;
display: block;
opacity: 0;
transition: opacity 0.2s ease;
`;
document.body.appendChild(el);
}

el.innerHTML = msg;
requestAnimationFrame(() => {
el.style.opacity = '1';
});

clearTimeout(el._hideTimer);
el._hideTimer = setTimeout(() => {
el.style.opacity = '0';
}, 1800);
}

// 监听原生 copy 行为
document.addEventListener('copy', function () {
const selection = window.getSelection().toString().trim();
if (selection.length >= 10) {
// Telegram 震动反馈
Telegram?.WebApp?.HapticFeedback?.notificationOccurred("success");

// 手机浏览器震动反馈
navigator.vibrate?.([50, 30, 50]);

// 提示框
showToast(`
<div style="display: flex; align-items: center; gap: 8px;">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none"
xmlns="http://www.w3.org/2000/svg" style="flex-shrink: 0;">
<path d="M9 9H5C4.44772 9 4 9.44772 4 10V19C4 19.5523 4.44772 20 5 20H14C14.5523 20 15 19.5523 15 19V15"
stroke="#ffffff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<rect x="9" y="4" width="11" height="11" rx="2"
stroke="#ffffff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
<span style="max-width: 80%; display: inline-block; word-break: break-word; overflow-wrap: break-word;">
Copied: ${selection}
</span>
</div>
`);
}
});
</script>

🧪 效果说明

场景 效果
手机原生复制 可触发提示与震动
Telegram 小程序复制行为 可触发提示与 Telegram 震动
PC 长按选中复制 可触发提示框
长串无空格字符串 自动换行显示,防止溢出

📌 注意事项

  • selection.length >= 10 是为了过滤误触和空行复制;
  • 弹窗设计使用 max-width: 90% 并让内容换行防止溢出;
  • 可根据视觉需求自定义提示样式;
  • navigator.vibrate 在桌面浏览器大多数无效,仅手机生效;
  • Telegram.WebApp.HapticFeedback 仅限在 Telegram 小程序中生效。

📎 应用场景

  • Telegram WebApp 项目
  • 移动端博客或文章页面
  • 支持原生复制监听的轻量网页应用