本文档在线地址:https://www.bidianer.com/blog/detail/15159378?bid=1276572 会员标志代码:
非会员标志代码:
油猴代码: // ==UserScript== // @name 笔点会员身份替换 // @namespace https://AiiyiYei.com/tihuan // @version 5.20 // @description 解决切换页面后第一个文本不替换的问题 // @match *://*.bidianer.com/* // @grant none // @run-at document-load // ==/UserScript== (function() { // -------------------------- 配置区 -------------------------- const classList = [ { target: 'vip-badge', add: 'active' }, ]; const textList = [ { target: '非会员', replacement: '至尊 VIP' }, // 第一个要重点处理的文本 { target: ',购买高级会员获得更多权益!', replacement: '(终身版)' }, { target: '2021年02月26日 注册', replacement: '2014年04月15日 注册' }, ]; // 可选:填写内容容器选择器(从F12复制,如".content",加快定位) const contentSelector = ''; // ------------------------------------------------------------ function escapeRegExp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); } function log(type, message) { console.log(`%c[稳定版脚本] [${type}] ${message}`, 'color: #4CAF50;'); } // 处理class function processClasses(element) { if (!element || element.nodeType !== Node.ELEMENT_NODE) return; classList.forEach(item => { if (element.classList.contains(item.target) && !element.classList.contains(item.add)) { element.classList.add(item.add); log('class替换', `成功:${item.target}`); } }); element.childNodes.forEach(child => processClasses(child)); } // 处理文本(重点强化第一个文本的匹配) function processTexts(node) { // 跳过script/style if (node.nodeType === Node.ELEMENT_NODE) { const tag = node.tagName.toLowerCase(); if (tag === 'script' || tag === 'style') return; // 处理输入框 if (tag === 'input' || tag === 'textarea') { textList.forEach(item => { if (node.value.includes(item.target)) { node.value = node.value.replace(new RegExp(escapeRegExp(item.target), 'g'), item.replacement); log('文本替换', `输入框:${item.target} → ${item.replacement}`); } }); } } // 处理普通文本节点(优先检查第一个文本) if (node.nodeType === Node.TEXT_NODE) { // 先处理第一个文本(确保优先匹配) const firstText = textList[0]; if (node.nodeValue.includes(firstText.target)) { node.nodeValue = node.nodeValue.replace(new RegExp(escapeRegExp(firstText.target), 'g'), firstText.replacement); log('文本替换', `第一个文本成功:${firstText.target} → ${firstText.replacement}`); } // 再处理其他文本 textList.slice(1).forEach(item => { if (node.nodeValue.includes(item.target)) { node.nodeValue = node.nodeValue.replace(new RegExp(escapeRegExp(item.target), 'g'), item.replacement); log('文本替换', `${item.target} → ${item.replacement}`); } }); } node.childNodes.forEach(child => processTexts(child)); } // 核心替换函数 function fullReplace() { log('替换触发', '开始扫描替换...'); // 优先处理指定容器(更快) let targetElement = document.body; if (contentSelector) { const container = document.querySelector(contentSelector); if (container) targetElement = container; } processClasses(targetElement); processTexts(targetElement); } // 动态监听(强化新增节点捕获) const observer = new MutationObserver(mutations => { mutations.forEach(mutation => { // 处理所有新增节点(包括嵌套深层的) mutation.addedNodes.forEach(addedNode => { if (addedNode.nodeType === Node.ELEMENT_NODE || addedNode.nodeType === Node.TEXT_NODE) { log('动态新增', `处理节点:${addedNode.nodeName}`); processClasses(addedNode); processTexts(addedNode); } }); }); }); observer.observe(document, { childList: true, subtree: true, // 确保深层节点也被监听 attributes: true, attributeFilter: ['class'] }); // -------------------------- 强化页面切换处理 -------------------------- function handlePageChange() { log('页面切换', '检测到路由变化,启动多轮替换...'); // 增加重试次数和延迟(覆盖更慢的加载) const delays = [300, 800, 1500, 2500, 4000]; // 0.3s~4s,共5次 delays.forEach(ms => { setTimeout(() => { log('页面切换重试', `延迟${ms}ms执行替换`); fullReplace(); }, ms); }); } // 监听所有可能的页面切换事件 window.addEventListener('popstate', handlePageChange); window.addEventListener('hashchange', handlePageChange); // 额外监听可能的SPA路由库事件(如history.pushState) const originalPushState = history.pushState; history.pushState = function(...args) { originalPushState.apply(this, args); handlePageChange(); // 拦截pushState调用,触发替换 }; // ---------------------------------------------------------------------- // 初始替换+重试 fullReplace(); setTimeout(fullReplace, 1000); setTimeout(fullReplace, 3000); log('启动完成', `已强化页面切换处理,共${delays.length}次重试`); })();