本文档在线地址: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}次重试`);
})();