diff --git a/src/config/i18n.js b/src/config/i18n.js index 6b7c7d8..fed017a 100644 --- a/src/config/i18n.js +++ b/src/config/i18n.js @@ -169,6 +169,30 @@ export const I18N = { zh: `翻译服务`, en: `Translate Service`, }, + mouseover_translation: { + zh: `鼠标悬停翻译`, + en: `Mouseover translation`, + }, + mk_disable: { + zh: `禁用`, + en: `Disable`, + }, + mk_none: { + zh: `鼠标悬停`, + en: `Mouseover`, + }, + mk_control: { + zh: `Control + 鼠标悬停`, + en: `Control + Mouseover`, + }, + mk_shift: { + zh: `Shift + 鼠标悬停`, + en: `Shift + Mouseover`, + }, + mk_alt: { + zh: `Alt + 鼠标悬停`, + en: `Alt + Mouseover`, + }, from_lang: { zh: `原文语言`, en: `Source Language`, diff --git a/src/config/index.js b/src/config/index.js index a105bfa..6c7d5cb 100644 --- a/src/config/index.js +++ b/src/config/index.js @@ -162,6 +162,19 @@ export const OPT_STYLE_USE_COLOR = [ OPT_STYLE_HIGHLIGHT, ]; +export const OPT_MOUSEKEY_DISABLE = "mk_disable"; +export const OPT_MOUSEKEY_NONE = "mk_none"; +export const OPT_MOUSEKEY_CONTROL = "mk_control"; +export const OPT_MOUSEKEY_SHIFT = "mk_shift"; +export const OPT_MOUSEKEY_ALT = "mk_alt"; +export const OPT_MOUSEKEY_ALL = [ + OPT_MOUSEKEY_DISABLE, + OPT_MOUSEKEY_NONE, + OPT_MOUSEKEY_CONTROL, + OPT_MOUSEKEY_SHIFT, + OPT_MOUSEKEY_ALT, +]; + export const DEFAULT_FETCH_LIMIT = 10; // 默认最大任务数量 export const DEFAULT_FETCH_INTERVAL = 100; // 默认任务间隔时间 @@ -242,6 +255,7 @@ export const DEFAULT_SETTING = { subrulesList: DEFAULT_SUBRULES_LIST, // 订阅列表 owSubrule: DEFAULT_OW_RULE, // 覆写订阅规则 transApis: DEFAULT_TRANS_APIS, // 翻译接口 + mouseKey: OPT_MOUSEKEY_DISABLE, // 鼠标悬停翻译 }; export const DEFAULT_RULES = [GLOBLA_RULE]; diff --git a/src/libs/translator.js b/src/libs/translator.js index c251070..29e511d 100644 --- a/src/libs/translator.js +++ b/src/libs/translator.js @@ -7,6 +7,7 @@ import { OPT_STYLE_DASHLINE, OPT_STYLE_FUZZY, SHADOW_KEY, + OPT_MOUSEKEY_DISABLE, } from "../config"; import Content from "../views/Content"; import { updateFetchPool, clearFetchPool } from "./fetch"; @@ -37,6 +38,7 @@ export class Translator { "iframe", ]; _eventName = genEventName(); + _keydownNow = ""; // 显示 _interseObserver = new IntersectionObserver( @@ -228,9 +230,41 @@ export class Translator { }); this._tranNodes.forEach((_, node) => { - // 监听节点显示 - this._interseObserver.observe(node); + if ( + !this._setting.mouseKey || + this._setting.mouseKey === OPT_MOUSEKEY_DISABLE + ) { + // 监听节点显示 + this._interseObserver.observe(node); + } else { + // 监听鼠标悬停 + node.addEventListener("mouseover", this._handleMouseover); + } }); + + // 监听键盘事件 + window.addEventListener("keydown", this._handleKeydown); + window.addEventListener("keyup", this._handleKeyup); + }; + + _handleMouseover = (e) => { + if ( + this._keydownNow && + this._setting?.mouseKey?.endsWith(this._keydownNow) + ) { + e.target.removeEventListener("mouseover", this._handleMouseover); + this._render(e.target); + } + }; + + _handleKeydown = (e) => { + console.log("keydown", e.key); + this._keydownNow = e.key.toLowerCase(); + }; + + _handleKeyup = (e) => { + console.log("keyup", e.key); + this._keydownNow = ""; }; _unRegister = () => { @@ -238,13 +272,29 @@ export class Translator { this._mutaObserver.disconnect(); // 解除节点显示监听 - this._interseObserver.disconnect(); + // this._interseObserver.disconnect(); - // 移除已插入元素 this._tranNodes.forEach((_, node) => { + if ( + !this._setting.mouseKey || + this._setting.mouseKey === OPT_MOUSEKEY_DISABLE + ) { + // 解除节点显示监听 + this._interseObserver.unobserve(node); + } else { + // 移除鼠标悬停监听 + node.removeEventListener("mouseover", this._handleMouseover); + } + + // 移除已插入元素 node.querySelector(APP_LCNAME)?.remove(); }); + // 解除监听键盘 + window.removeEventListener("keydown", this._handleKeydown); + window.removeEventListener("keyup", this._handleKeyup); + this._keydownNow = ""; + // 清空节点集合 this._rootNodes.clear(); this._tranNodes.clear(); diff --git a/src/views/Options/Setting.js b/src/views/Options/Setting.js index 4cbf0db..480f55d 100644 --- a/src/views/Options/Setting.js +++ b/src/views/Options/Setting.js @@ -11,7 +11,13 @@ import { useSetting } from "../../hooks/Setting"; import { limitNumber } from "../../libs/utils"; import { useI18n } from "../../hooks/I18n"; import { useAlert } from "../../hooks/Alert"; -import { UI_LANGS, TRANS_NEWLINE_LENGTH, CACHE_NAME } from "../../config"; +import { + UI_LANGS, + TRANS_NEWLINE_LENGTH, + CACHE_NAME, + OPT_MOUSEKEY_ALL, + OPT_MOUSEKEY_DISABLE, +} from "../../config"; export default function Settings() { const i18n = useI18n(); @@ -61,6 +67,7 @@ export default function Settings() { maxLength, clearCache, newlineLength = TRANS_NEWLINE_LENGTH, + mouseKey = OPT_MOUSEKEY_DISABLE, } = setting; return ( @@ -127,6 +134,22 @@ export default function Settings() { onChange={handleChange} /> + + {i18n("mouseover_translation")} + + + {i18n("if_clear_cache")}