You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让按键统计JS脚本稳定运行并正确封装为Chrome扩展

问题原因与修复方案

核心故障点

  • 剪贴板API参数错误:navigator.clipboard.writeText传入的是window.getSelection()返回的Selection对象,而非字符串,会直接触发参数错误,未捕获的异常会导致后续代码静默跳过。
  • 异步逻辑不规范:剪贴板读写都是异步操作,当前嵌套then的写法未处理异常也未保证执行顺序,频繁触发时容易出现竞态,触发浏览器的操作频率限制后会直接静默失效。
  • 事件绑定不稳定:将快捷键事件绑定在body节点上,当页面动态替换body内容、或其他脚本阻止了keydown事件冒泡时,绑定的事件会直接丢失。
  • 无异常捕获逻辑:未对异步操作、DOM操作做异常捕获,只要某一步出现报错(比如#insert节点不存在、剪贴板权限不足),就会导致后续全部逻辑中断,出现代码块随机跳过的现象。
  • 内存存储限制:当前storage变量存在于内存中,页面刷新、扩展popup关闭都会导致数据丢失,若存在重复绑定事件的情况,还会出现变量覆盖的问题。

修复后的完整代码

document.addEventListener("DOMContentLoaded", function() {
  // 绑定在document上避免节点替换导致事件丢失
  document.addEventListener("keydown", copy_paste);
});

console.log('It connected');

// 可以根据需要换成chrome.storage.local实现持久化存储
let storage = {};

async function copy_paste(e) {
  // 匹配快捷键,加阻止默认避免冲突
  if (e.ctrlKey && e.key.toLowerCase() === "q") {
    e.preventDefault();
    try {
      // 把Selection对象转成字符串
      const selectedText = window.getSelection().toString().trim();
      if (!selectedText) return; // 无选中文本直接跳过
      // 按顺序执行剪贴板读写
      await navigator.clipboard.writeText(selectedText);
      const text = await navigator.clipboard.readText();
      // 更新计数
      storage[text] = (storage[text] || 0) + 1;
      mySort(storage);
    } catch (err) {
      // 捕获错误避免中断后续逻辑,可自行加日志排查
      console.error('操作失败:', err);
    }
  }
}

function show(arrStorage) {
  try {
    const parent = document.getElementById("insert");
    // 节点不存在直接跳过,避免报错
    if (!parent) return;
    parent.innerHTML = "";
    for (let i = 0; i < arrStorage.length; i++) {
      const para = document.createElement("h4");
      para.innerText = `${arrStorage[i][0]} : ${arrStorage[i][1]}`;
      parent.appendChild(para);
    }
  } catch (err) {
    console.error('渲染失败:', err);
  }
}

function mySort(storage) {
  const arrStorage = Object.entries(storage).sort((a, b) => b[1] - a[1]);
  show(arrStorage);
}

额外适配注意事项

  • 若作为Chrome扩展使用,需要在manifest.json中声明clipboardRead、clipboardWrite权限,避免权限不足导致操作失败。
  • 如果是作为content script注入到页面,需要添加防抖逻辑避免事件重复绑定,同时可以用chrome.storage.local替换内存storage实现跨页面持久化。
  • 快捷键触发需要在页面激活的状态下操作,若焦点在地址栏、浏览器控件上时事件不会触发。

内容的提问来源于stack exchange,提问作者FuQ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 00:06:03