尝试用 JS 给浏览器写个 Vim 按键模拟,好像没大毛病
我在浏览器上面也安装了 Vim 按键模拟扩展,Vimium - The Hacker's Browser,已经使用多年。
怎么说呢,确实是个“大而全”的 Vim 按键模拟。
但是,这么多年下来,我发现我几乎只需要使用其中的 gg
, G
, x
, r
, t
等非常少数的几个。
而 Bugs 呢,却发现了不少。最明显的例子,有几类页面可能不能正常工作:不是用标准 <input>
/<textarea>
作为输入框的、用 <div contenteditible>
来输入的)不能正确使用。所以当访问类似 jslinux 的页面时,要么:
- 禁用掉整个扩展(麻烦!);
- 按
i
进入Insert
模式(all commands will be ignored until you hit Esc to exit); - 把网页添加到 Vimium 的白名单(还要写正则/通配符,没有测试!);
总之就是,奇奇怪怪,影响编辑/使用体验。再加上此扩展本身体积很大(几百KB)、还申请了很多的隐私🔏类权限等等。 所以,我就想,写一个类似的东西到底有多难?
如何模拟?
我没参考任何已有代码,只是按照我的想法尝试做了以下的步骤:
- 在页面的根元素上监听按键(KeyPress)事件;
- 同时会接受到来自其它子元素的事件,因为事件会冒泡,所以要判断事件是来自
body
本身的; - 判断事件来自
body
来自也就不会来自<input> / <textarea> / <div contenteditible>
等元素。 - 由于大概率是冒泡来的事件,如果页面本身没处理,我
body
处理一下应该没啥问题吧?
- 同时会接受到来自其它子元素的事件,因为事件会冒泡,所以要判断事件是来自
- 把事件中的按键字符加入到一个按键栈里面;
- 检查按键栈是否属于某个已绑定的操作
- 如果是,执行对应的操作;
- 如果不是,则清空栈。
写点儿代码?
好像上面描述的步骤就足够了,然后就尝试写了点儿,两个函数,100+ 行代码。
用了几天,好像没啥毛病🤔。但是 Vimium 可是有 ~5000 的 Git 提交量。我这 100+ 行代码能不能换像它一样的 22K Stars? 代码不多,我全部贴出来吧(我 JS 并不熟悉,写得只是刚好能工作的程度,香草味的):
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 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
|
最快速的体验方式:复制以上代码,打开浏览器的控制台,粘贴并执行!然后就可以在任何页面上体验了。 当然,我的博客 fork 了一份相同的代码,不管你愿不愿意,已经是被迫尝试了🐶。
预定义的按键可以在页面上按 ?
输出到控制台里面:
(索引) | 值 |
---|---|
gg | 回到页首 |
G | 回到页尾 |
j | 向下滚动 |
k | 向上滚动 |
f | 进入全屏 |
r | 刷新 |
b | 回到首页 |
作为扩展/Web Extension
根据 Mozilla 的 Web Extension 教程,加个 manifest.json
就可以作为 Web Extension 来使用了,简直简单到另人发指,连打包都不用:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
|
用火狐打开的 about:debugging
页面,点击“加载临时组件”,选中 manifest.json
所在目录即可加载。
我没用 Chrome 和 Safari,不知道如何操作。
正式版
尝试上架到火狐官方扩展商店,竟然很容易地成功了。可以直接点击下面的链接安装:
虽然权限一栏提示说会“Access your data for all websites”,但是实际上并没有访问任何数据。 只是我不知道怎么消除这个提示。
亲,给个好评!