[JS/油猴] 通杀所有悬浮搜索框
本帖最后由 三滑稽甲苯 于 2023-6-2 14:35 编辑## 前言
在浏览网页的时候,总会有那么几个网站,在你选择了文本后给你弹出一个悬浮框,让你可以 *方便* 地在它的搜索引擎上搜索。实际上,我们往往只是想要复制,或者只是下意识地双击选择(不知道有没有人和我一样有这样的习惯),而跳出来的搜索框很容易误触。终于,某一天我忍无可忍,决定下手解决这种情况。
!(https://greasyfork.org/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBNTJyQVE9PSIsImV4cCI6bnVsbCwicHVyIjoiYmxvYl9pZCJ9fQ==--e99afb87ef52a331d95d7054a84f9a1ed036c97d/searchbox.jpg) !(https://greasyfork.org/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBNkdyQVE9PSIsImV4cCI6bnVsbCwicHVyIjoiYmxvYl9pZCJ9fQ==--2aafa598badaa236ecbb355d54f81a20bb7f3ce1/google.jpg) !(https://greasyfork.org/rails/active_storage/blobs/redirect/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBNEN2QVE9PSIsImV4cCI6bnVsbCwicHVyIjoiYmxvYl9pZCJ9fQ==--4f2c19e872cafab235615eb78b80897c7abe2828/csdn.jpg)
## 思路
经过 F12 分析后,发现绝大多数网站都是通过监听 `selectionchange` 和 `mouseup` 这两种事件来控制悬浮框的展现。于是,一个通杀方案浮现在脑海之中,那就是移除所有监听这两个事件的监听器。但是[移除监听器需要知道它的回调函数](https://developer.mozilla.org/zh-CN/docs/Web/API/EventTarget/removeEventListener#%E5%8C%B9%E9%85%8D%E8%A6%81%E5%88%A0%E9%99%A4%E7%9A%84%E4%BA%8B%E4%BB%B6%E7%9B%91%E5%90%AC%E5%99%A8),而我们很难做到通用地获取回调函数 (通过覆写 `addEventListener` 方法可以做到劫持,但是这么做可能导致意料之外的错误)。
在翻看了十段甚至九段文档后,我发现了一个[参数](https://developer.mozilla.org/zh-CN/docs/Web/API/EventTarget/addEventListener#%E5%8F%82%E6%95%B0):
> `options` (可选)
> 一个指定有关 listener 属性的可选参数对象。可用的选项如下:
> - `capture` (可选)
> 一个布尔值,表示 listener 会在该类型的 **事件捕获阶段** 传播到该 EventTarget 时触发。
要弄明白上述参数的含义,得首先弄清楚 js 的[事件顺序](https://www.quirksmode.org/js/events_order.html#link4)。当某个元素发起事件时,首先从最顶层传播至发起的元素,然后再次折返传播到最顶层。第一趟称为事件捕获阶段 (Event capturing),第二趟称为事件冒泡阶段 (Event bubbling)。用人话来说就是 **`capture` 为真时,最顶层的事件监听器会首先获得事件通知**。
同时我们知道,在事件监听器的回调函数中,我们可以 **调用 `stopImmediatePropagation` 来立刻阻止事件传播**。那么,一个优雅而又通用的解决方案就呼之欲出了。
## 最终方案
1. 我们直接在整个 `document` 上设立关于 `selectionchange` 和 `mouseup` 的监听器,`capture` 设为 `true`,从而保证我们的侦听器是最早获得事件通知的
2. 当我们的侦听器得到通知后,调用 `stopImmediatePropagation` 来立刻阻止事件传播
3. 目标网站设立的侦听器无法捕获事件 (因为已经被我们的侦听器截获了)
用人话来讲,就是我们设立了一个侦听器,截获了所有相关事件,导致网站设立的侦听器 *不知道* 这些事件,于是悬浮框也就不会出现了。需要注意的是,有些网站是通过这两类事件来提供其它有用的服务,在这种情况下只能使用其它方法了(这类网站大概率也不会搞个悬浮框来恶心用户吧)。
## 代码
> Talk is cheap, show me the code.
```javascript
// 核心代码
["selectionchange", "mouseup"].forEach((type) => {
document.addEventListener(type, (e) => {
e.stopImmediatePropagation();
}, {capture: true});
});
```
**油猴**:https://greasyfork.org/zh-CN/scripts/466779-%E7%A6%81%E7%94%A8%E6%90%9C%E7%B4%A2%E6%A1%86
注意:对于不在脚本内置列表内的网站,你可以手动将其 **添加至用户匹配列表** 来使脚本生效,详见链接内的截图。 本帖最后由 pjy612 于 2023-6-2 15:05 编辑
懂了。。。 只是 易误触 嫌烦 。。。 不容易消掉。。。
下面可以无视。。。
==========================
感觉这是主要用于手机吗?
PS.话说哪些手机浏览器App 能用油猴之类的?
pjy612 发表于 2023-6-2 15:02
懂了。。。 只是 易误触 嫌烦 。。。 不容易消掉。。。
主要是电脑,手机的话就是事件不同,原理一样,不用做太大的改动
可以用油猴的有kiwi, via等,很多的,搜一下一大把 感谢感谢 这个好用
这个真的很不错欸,在脚本页找到了作者的其他脚本,超级好用!! 本帖最后由 zhenjinren520 于 2023-6-13 15:29 编辑
每次搜索时候,右侧就会弹出一个小的搜索框,非常麻烦,楼主这个我先用来试试 wkdxz 发表于 2023-6-2 16:14
这个真的很不错欸,在脚本页找到了作者的其他脚本,超级好用!!
感谢支持{:301_997:} 这个可以有,支持