// ==UserScript== // @name 中文段落遮挡助手 // @namespace http://tampermonkey.net/ // @version 0.6 // @description 保留纯英文段落,遮挡中文段落(含其中的英文缩写) // @author 基尼胎美 // @match *://*/* // @grant GM_addStyle // @license MIT // @downloadURL https://update.greasyfork.icu/scripts/554508/%E4%B8%AD%E6%96%87%E6%AE%B5%E8%90%BD%E9%81%AE%E6%8C%A1%E5%8A%A9%E6%89%8B.user.js // @updateURL https://update.greasyfork.icu/scripts/554508/%E4%B8%AD%E6%96%87%E6%AE%B5%E8%90%BD%E9%81%AE%E6%8C%A1%E5%8A%A9%E6%89%8B.meta.js // ==/UserScript== (function() { 'use strict'; // 按钮样式 GM_addStyle(` .chinese-toggle-btn { position: fixed; top: 20px; right: 20px; z-index: 999999; padding: 10px 15px; background: #f39c12; color: white; border: none; border-radius: 6px; cursor: pointer; font-size: 14px; box-shadow: 0 2px 5px rgba(0,0,0,0.2); transition: all 0.3s; } .chinese-toggle-btn:hover { background: #d35400; transform: translateY(-2px); } `); // 创建切换按钮 const toggleBtn = document.createElement('button'); toggleBtn.className = 'chinese-toggle-btn'; toggleBtn.textContent = '遮挡中文段落'; document.body.appendChild(toggleBtn); // 状态管理 let isHidden = false; const chineseCharRegex = /[\u4e00-\u9fa5]/; // 用于判断是否含中文字符 const allCharsRegex = /./g; // 匹配所有字符(中文段落中全部处理) const originalTextAttr = 'data-original-text'; // 保存原始文本的属性 // 判断一个元素是否包含中文字符(用于区分中英文段落) function hasChineseCharacters(element) { return chineseCharRegex.test(element.textContent); } // 找到文本节点所在的"段落级"父元素(优先块级元素,如p、div等) function getParagraphElement(textNode) { let parent = textNode.parentNode; // 向上查找最近的块级元素或语义化段落元素 while (parent && parent !== document.body) { const display = getComputedStyle(parent).display; if (display.includes('block') || ['P', 'DIV', 'SECTION', 'ARTICLE', 'LI', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6'].includes(parent.tagName)) { return parent; } parent = parent.parentNode; } return document.body; // 找不到则默认body } // 处理单个文本节点 function processTextNode(node, hide) { // 跳过不需要处理的节点(脚本、样式、输入框等) if (node.nodeType !== Node.TEXT_NODE || !node.parentNode || ['SCRIPT', 'STYLE', 'NOSCRIPT', 'IFRAME', 'INPUT', 'TEXTAREA', 'SELECT'].includes(node.parentNode.tagName)) { return; } // 找到文本节点所在的段落元素 const paragraph = getParagraphElement(node); // 判断是否为中文段落(含中文字符) const isChineseParagraph = hasChineseCharacters(paragraph); if (hide && isChineseParagraph) { // 中文段落且需要遮挡:保存原始文本,移除所有内容 if (!node[originalTextAttr]) { node[originalTextAttr] = node.nodeValue; // 保存原始文本 node.nodeValue = node.nodeValue.replace(allCharsRegex, ''); // 清空所有字符 } } else if (!hide) { // 恢复原始文本(无论是否中文段落,有保存就恢复) if (node[originalTextAttr]) { node.nodeValue = node[originalTextAttr]; delete node[originalTextAttr]; } } // 英文段落无论是否遮挡,都不处理(保持原样) } // 遍历所有文本节点处理 function processAllTextNodes(hide) { const walker = document.createTreeWalker( document.body, NodeFilter.SHOW_TEXT, null, false ); let currentNode; while (currentNode = walker.nextNode()) { processTextNode(currentNode, hide); } console.log(`已${hide ? '遮挡所有中文段落' : '恢复所有段落'}`); } // 按钮点击事件 toggleBtn.addEventListener('click', () => { isHidden = !isHidden; toggleBtn.textContent = isHidden ? '恢复所有段落' : '遮挡中文段落'; processAllTextNodes(isHidden); }); // 监听动态加载内容 const observer = new MutationObserver(mutations => { if (isHidden) { mutations.forEach(mutation => { mutation.addedNodes.forEach(node => { if (node.nodeType === Node.ELEMENT_NODE) { const walker = document.createTreeWalker( node, NodeFilter.SHOW_TEXT, null, false ); let currentNode; while (currentNode = walker.nextNode()) { processTextNode(currentNode, true); } } else if (node.nodeType === Node.TEXT_NODE) { processTextNode(node, true); } }); }); } }); observer.observe(document.body, { childList: true, subtree: true, characterData: true }); console.log('中英文段落分离遮挡助手已加载,点击右上角按钮切换状态'); })();