04月05, 2023

解决一个浏览器插件开发中的按键监听问题

以前我一直在用一个叫做ContextSearch的划词搜索扩展程序,在浏览器中按住ctrl键,选中一段文字后,可以弹出一个界面让你选择你想要的搜索引擎(可配置)进行搜索。

然而这个扩展程序不知道是什么原因,近两年被下架了,估计是作者没有在Chrome WebStore上更新一些东西吧。

image.png

于是我把源码下下来改造成了Tampermonkey可用的样子,顺便加上了时间戳转换的功能,自己用。


但是,这个扩展程序有个非常令人苦恼的BUG一直没有解决,就是会偶现没有按住ctrl键的情况下,选中文字也会弹出搜索框。

我针对ctrl键的监听代码是这样的:

document.addEventListener(
  "keydown",
  function (event) {
    ctrlKey = event.ctrlKey;
  },
  true
);

document.addEventListener(
  "keyup",
  function (event) {
    ctrlKey = event.ctrlKey;
  },
  true
);

乍一看好像没问题,在任意按键按下或弹起时,均会把ctrl键的状态存下来。这个问题困扰了我很久,主要是一直是偶现,找不到复现路径,就不知道该从哪查起。

今天突然意识到,这里面遗漏了一个可能性,就是如果浏览器没有感知到ctrl键的弹起,且后续也没有按任何按键的话,那么记录下来的ctrl键的状态就一直都是按下的状态。

那什么情况会产生这种问题呢?答案是浏览器的失焦!如果在按住ctrl键的状态下,使用鼠标点击了浏览器以外的软件,使得浏览器失焦,然后弹起了ctrl键,那么浏览器就捕捉不到这次ctrl键的弹起。

找到问题的原因,解决方案就比较明确了,针对页面失焦监听一下事件即可:

window.addEventListener(
  "blur",
  function (event) {
    ctrlKey = false;
  },
  true
);

本文链接:https://debug.fanzheng.org/post/solve-a-problem-of-key-event-listening-in-the-development-of-a-browser-plug-in.html

-- EOF --

Comments

评论加载中...

注:如果长时间无法加载,请针对 disq.us | disquscdn.com | disqus.com 启用代理。