(mouseX, mouseY, time, noSkip = true)
| 754 | |
| 755 | // 监听事件处理器,参数:鼠标坐标、计时器 |
| 756 | function handler(mouseX, mouseY, time, noSkip = true) { |
| 757 | if (noSkip && !shortcutManager.hotkeyPressed) return; |
| 758 | |
| 759 | clearTimeout(hoverTimer); // 清除计时器 |
| 760 | hoverTimer = setTimeout(() => { |
| 761 | let node = getTransNode(document.elementFromPoint(mouseX, mouseY)); // 获取最终需要翻译的节点 |
| 762 | if (!node) return; // 如果不需要翻译,则跳过 |
| 763 | |
| 764 | if (hasLoadingSpinner(node)) { // 如果已经在翻译,则跳过 |
| 765 | // console.log('正在翻译中...跳过'); |
| 766 | return; |
| 767 | // }else { |
| 768 | // console.log('翻译节点:', node); |
| 769 | } |
| 770 | |
| 771 | // 去重判断 |
| 772 | let outerHTMLTemp = node.outerHTML; |
| 773 | if (outerHTMLSet.has(outerHTMLTemp)) { |
| 774 | // console.log('重复节点', node); |
| 775 | return; |
| 776 | } |
| 777 | outerHTMLSet.add(outerHTMLTemp); |
| 778 | |
| 779 | // 检测缓存 cache |
| 780 | let outerHTMLCache = localStorageManager.getTransCache(node.outerHTML); |
| 781 | if (outerHTMLCache) { |
| 782 | // console.log("缓存命中:", outerHTMLCache); |
| 783 | let spinner = createLoadingSpinner(node, true); |
| 784 | setTimeout(() => { // 延迟 remove 转圈动画与替换文本 |
| 785 | spinner.remove(); |
| 786 | outerHTMLSet.delete(outerHTMLTemp); |
| 787 | let fn = compatFn[url.host]; // 兼容函数 |
| 788 | if (fn) { |
| 789 | fn(node, outerHTMLCache); // 兼容函数 |
| 790 | } else { |
| 791 | node.outerHTML = safeFluentRead ? safeFluentRead.createHTML(outerHTMLCache) : outerHTMLCache; |
| 792 | } |
| 793 | delayRemoveCache(outerHTMLCache); |
| 794 | }, 250); |
| 795 | return; |
| 796 | } |
| 797 | |
| 798 | translate(node); |
| 799 | }, time); |
| 800 | } |
| 801 | |
| 802 | const getTransNodeSet = new Set(['span']); |
| 803 | // 特例集合 |
no test coverage detected