您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
在 www.whitehouse.gov 网站上将“Donald J. Trump”及其变体的字体加粗加大,并在鼠标悬停时隐藏光标,以提高可见性。
// ==UserScript== // @name Highlight Trump Name & Hide Cursor on Hover on Whitehouse.gov (For Accessibility) // @name:zh-CN 高亮白宫网站上的特朗普名字,并在悬停时隐藏光标 (视障辅助) // @namespace http://tampermonkey.net/ // @version 1.1 // @description Highlights mentions of Donald J. Trump on www.whitehouse.gov with bold/larger font and hides the cursor when hovering over them for better visibility. // @description:zh-CN 在 www.whitehouse.gov 网站上将“Donald J. Trump”及其变体的字体加粗加大,并在鼠标悬停时隐藏光标,以提高可见性。 // @author Lyragosa // @match *://www.whitehouse.gov/* // @grant GM_addStyle // @run-at document-idle // @license MIT // ==/UserScript== (function() { 'use strict'; // --- 配置 --- const highlightStyleClass = 'highlighted-trump-name-vz'; // 自定义CSS类名,避免冲突 const patternsToHighlight = [ /\bPresident\s+Donald\s+J\.\s+Trump\b/gi, // President Donald J. Trump /\bPresident\s+Trump\b/gi, // President Trump /\bDonald\s+J\.\s+Trump\b/gi, // Donald J. Trump /\bTrump\b/gi // 单独的 "Trump" ]; // --- CSS 样式 --- // 更新:增加了 :hover 规则来隐藏光标 const cssStyle = ` .${highlightStyleClass} { font-weight: bold !important; font-size: 1.2em !important; /* 比周围文字大20% */ /* 可以添加其他样式 */ } /* 新增:当鼠标悬停在高亮的span上时,隐藏光标 */ .${highlightStyleClass}:hover { cursor: none !important; } `; // --- 注入CSS样式 --- GM_addStyle(cssStyle); // --- 核心处理函数 --- function highlightTextInNode(node) { const walker = document.createTreeWalker( node, NodeFilter.SHOW_TEXT, { acceptNode: function(textNode) { if (textNode.parentNode.nodeName === 'SCRIPT' || textNode.parentNode.nodeName === 'STYLE') { return NodeFilter.FILTER_REJECT; } if (textNode.parentNode.classList.contains(highlightStyleClass)) { return NodeFilter.FILTER_REJECT; } if (textNode.nodeValue.trim() === '') { return NodeFilter.FILTER_SKIP; } for (const pattern of patternsToHighlight) { pattern.lastIndex = 0; if (pattern.test(textNode.nodeValue)) { return NodeFilter.FILTER_ACCEPT; } } return NodeFilter.FILTER_SKIP; } }, false ); let textNode; const nodesToProcess = []; while(textNode = walker.nextNode()) { nodesToProcess.push(textNode); } for (const nodeToProcess of nodesToProcess) { let currentNode = nodeToProcess; let nodeReplaced = false; // 标记节点是否已被替换 for (const pattern of patternsToHighlight) { if (nodeReplaced) break; // 如果节点已被替换,跳过后续模式对此节点的处理 pattern.lastIndex = 0; let match; let lastIndex = 0; const fragment = document.createDocumentFragment(); let foundMatchInPattern = false; while ((match = pattern.exec(currentNode.nodeValue)) !== null) { foundMatchInPattern = true; const matchedText = match[0]; const matchIndex = match.index; if (matchIndex > lastIndex) { fragment.appendChild(document.createTextNode(currentNode.nodeValue.substring(lastIndex, matchIndex))); } const span = document.createElement('span'); span.className = highlightStyleClass; span.textContent = matchedText; fragment.appendChild(span); lastIndex = pattern.lastIndex; } if (foundMatchInPattern) { if (lastIndex < currentNode.nodeValue.length) { fragment.appendChild(document.createTextNode(currentNode.nodeValue.substring(lastIndex))); } if (currentNode.parentNode) { currentNode.parentNode.replaceChild(fragment, currentNode); nodeReplaced = true; // 标记此原始节点已被替换 } } } } } // --- 初始执行 --- highlightTextInNode(document.body); // --- 监听DOM变化 (处理动态加载的内容) --- const observer = new MutationObserver(function(mutationsList) { for (const mutation of mutationsList) { if (mutation.type === 'childList' && mutation.addedNodes.length > 0) { mutation.addedNodes.forEach(function(addedNode) { if (addedNode.nodeType === Node.ELEMENT_NODE) { // 检查添加的节点本身或其父节点是否是高亮节点,避免递归触发 if (!addedNode.classList || !addedNode.classList.contains(highlightStyleClass)) { if (!addedNode.parentNode || !addedNode.parentNode.classList || !addedNode.parentNode.classList.contains(highlightStyleClass)){ highlightTextInNode(addedNode); } } } }); } } }); observer.observe(document.body, { childList: true, subtree: true }); })();