// ==UserScript== // @name 52pj帖子列表增强 // @match https://www.52pojie.cn/* // @version 3.1 // @description 实时监测并修改链接样式,集成可视化设置面板(支持回帖奖励、悬赏已解决、悬赏金额动态样式) // @author aura service // @grant GM_registerMenuCommand // @grant GM_setValue // @grant GM_getValue // @license ISC // ==/UserScript== (function() { 'use strict'; // ---------- 配置存储 ---------- const defaultStyles = { fontWeight: 'bold', color: 'red', fontSize: '16px' }; let styles = { fontWeight: GM_getValue('fontWeight', defaultStyles.fontWeight), color: GM_getValue('color', defaultStyles.color), fontSize: GM_getValue('fontSize', defaultStyles.fontSize) }; const defaultResolvedAction = 'mark'; const defaultResolvedBgColor = '#f0f0f0'; let resolvedAction = GM_getValue('resolvedAction', defaultResolvedAction); let resolvedBgColor = GM_getValue('resolvedBgColor', defaultResolvedBgColor); const REWARD_ENABLED_KEY = 'rewardEnabled'; const REWARD_RULES_KEY = 'rewardRules'; const defaultRewardRules = [ { min: 1, max: 9, style: { color: 'green', fontWeight: 'normal', fontSize: '', backgroundColor: '' } }, { min: 10, max: 49, style: { color: 'orange', fontWeight: 'bold', fontSize: '', backgroundColor: '' } }, { min: 50, max: 99, style: { color: 'red', fontWeight: 'bold', fontSize: '16px', backgroundColor: '' } }, { min: 100, max: null, style: { color: 'purple', fontWeight: 'bold', fontSize: '18px', backgroundColor: '#ffffcc' } } ]; let rewardEnabled = GM_getValue(REWARD_ENABLED_KEY, false); let rewardRules = GM_getValue(REWARD_RULES_KEY, defaultRewardRules); // 预设规则集 const presets = { default: defaultRewardRules, warm: [ { min: 1, max: 9, style: { color: '#d97706', fontWeight: 'normal', fontSize: '', backgroundColor: '' } }, { min: 10, max: 49, style: { color: '#c2410c', fontWeight: 'bold', fontSize: '15px', backgroundColor: '' } }, { min: 50, max: 99, style: { color: '#b91c1c', fontWeight: 'bold', fontSize: '16px', backgroundColor: '#fef3c7' } }, { min: 100, max: null, style: { color: '#7b341e', fontWeight: 'bold', fontSize: '18px', backgroundColor: '#ffedd5' } } ], cool: [ { min: 1, max: 9, style: { color: '#0284c7', fontWeight: 'normal', fontSize: '', backgroundColor: '' } }, { min: 10, max: 49, style: { color: '#075985', fontWeight: 'bold', fontSize: '15px', backgroundColor: '' } }, { min: 50, max: 99, style: { color: '#1e3a8a', fontWeight: 'bold', fontSize: '16px', backgroundColor: '#dbeafe' } }, { min: 100, max: null, style: { color: '#172554', fontWeight: 'bold', fontSize: '18px', backgroundColor: '#bfdbfe' } } ], highlight: [ { min: 1, max: 9, style: { color: 'black', fontWeight: 'normal', fontSize: '', backgroundColor: '#fef9c3' } }, { min: 10, max: 49, style: { color: 'black', fontWeight: 'bold', fontSize: '15px', backgroundColor: '#fde047' } }, { min: 50, max: 99, style: { color: 'black', fontWeight: 'bold', fontSize: '16px', backgroundColor: '#facc15' } }, { min: 100, max: null, style: { color: 'black', fontWeight: 'bold', fontSize: '18px', backgroundColor: '#eab308' } } ] }; // ---------- 辅助函数 ---------- function getStyleForReward(amount) { if (!rewardEnabled) return null; for (const rule of rewardRules) { if (amount >= rule.min && (rule.max === null || amount <= rule.max)) { return rule.style; } } return null; } // ---------- 核心处理函数(与之前相同)---------- function checkAndModify() { const rows = document.querySelectorAll('tbody tr'); rows.forEach(row => { // 回帖奖励 const ths = row.querySelectorAll('th.common, th.new'); let hasReward = false; ths.forEach(th => { const span = th.querySelector('span'); if (span && span.textContent.includes('回帖奖励')) hasReward = true; }); if (hasReward) { const links = row.querySelectorAll('th.common a.s.xst, th.new a.s.xst'); links.forEach(link => { link.style.fontWeight = styles.fontWeight; link.style.color = styles.color; link.style.fontSize = styles.fontSize; }); } // 悬赏已解决标记/隐藏 const rewardIcon = row.querySelector('td.icn img[src*="rewardsmall.gif"]'); if (rewardIcon) { const resolvedLink = Array.from(row.querySelectorAll('th a')).find(a => a.textContent.trim() === '[已解决]'); if (resolvedLink) { if (resolvedAction === 'mark') row.style.backgroundColor = resolvedBgColor; else if (resolvedAction === 'hide') row.style.display = 'none'; } } // 悬赏金额动态样式 if (rewardEnabled && rewardIcon) { const rewardLink = row.querySelector('th a[href*="specialtype=reward"]'); if (rewardLink) { const amountSpan = rewardLink.querySelector('span.xw1'); if (amountSpan) { const amount = parseInt(amountSpan.textContent.trim(), 10); if (!isNaN(amount)) { const style = getStyleForReward(amount); if (style) { const titleLink = row.querySelector('th.common a.s.xst, th.new a.s.xst'); if (titleLink) { for (const [prop, val] of Object.entries(style)) { if (val) titleLink.style[prop] = val; } } } } } } } }); } // ---------- 优化后的设置面板 ---------- let settingsPanel = null; function createSettingsPanel() { if (settingsPanel) { settingsPanel.style.display = settingsPanel.style.display === 'none' ? 'block' : 'none'; return; } // 创建面板容器 const panel = document.createElement('div'); panel.id = 'pj-settings-panel'; Object.assign(panel.style, { position: 'fixed', top: '60px', right: '20px', width: '560px', maxHeight: '80vh', overflowY: 'auto', backgroundColor: '#fff', border: 'none', borderRadius: '12px', boxShadow: '0 10px 25px rgba(0,0,0,0.15)', padding: '20px', zIndex: '9999', fontFamily: 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif', fontSize: '14px', display: 'block', transition: 'box-shadow 0.2s' }); // ----- 可拖动的标题栏 ----- const header = document.createElement('div'); Object.assign(header.style, { display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '16px', paddingBottom: '8px', borderBottom: '1px solid #eef2f6', cursor: 'move', userSelect: 'none' }); header.innerHTML = '

⚙️ 52pj 增强设置

'; const closeBtn = document.createElement('button'); closeBtn.textContent = '✕'; Object.assign(closeBtn.style, { background: 'none', border: 'none', fontSize: '18px', cursor: 'pointer', padding: '0 8px', color: '#64748b', borderRadius: '4px' }); closeBtn.onclick = () => panel.style.display = 'none'; header.appendChild(closeBtn); panel.appendChild(header); // 拖动逻辑 let isDragging = false, offsetX, offsetY; header.addEventListener('mousedown', (e) => { isDragging = true; offsetX = e.clientX - panel.offsetLeft; offsetY = e.clientY - panel.offsetTop; panel.style.transition = 'none'; }); document.addEventListener('mousemove', (e) => { if (!isDragging) return; panel.style.left = (e.clientX - offsetX) + 'px'; panel.style.top = (e.clientY - offsetY) + 'px'; panel.style.right = 'auto'; }); document.addEventListener('mouseup', () => { isDragging = false; panel.style.transition = ''; }); // ----- 回帖奖励样式卡片 ----- const section1 = document.createElement('div'); section1.style.marginBottom = '24px'; section1.innerHTML = '

📌 回帖奖励样式

'; const rewardStyleContainer = document.createElement('div'); rewardStyleContainer.style.display = 'flex'; rewardStyleContainer.style.gap = '12px'; rewardStyleContainer.style.flexWrap = 'wrap'; // 字体粗细 const weightGroup = document.createElement('div'); weightGroup.style.flex = '1 1 100px'; weightGroup.innerHTML = ''; const weightSelect = document.createElement('select'); weightSelect.style.width = '100%'; weightSelect.style.padding = '6px'; weightSelect.style.border = '1px solid #cbd5e1'; weightSelect.style.borderRadius = '6px'; weightSelect.innerHTML = ''; weightSelect.value = styles.fontWeight; weightGroup.appendChild(weightSelect); rewardStyleContainer.appendChild(weightGroup); // 颜色 const colorGroup = document.createElement('div'); colorGroup.style.flex = '1 1 100px'; colorGroup.innerHTML = ''; const colorInput = document.createElement('input'); colorInput.type = 'color'; colorInput.value = styles.color; colorInput.style.width = '100%'; colorInput.style.height = '34px'; colorInput.style.border = '1px solid #cbd5e1'; colorInput.style.borderRadius = '6px'; colorGroup.appendChild(colorInput); rewardStyleContainer.appendChild(colorGroup); // 字体大小 const sizeGroup = document.createElement('div'); sizeGroup.style.flex = '1 1 100px'; sizeGroup.innerHTML = ''; const sizeInput = document.createElement('input'); sizeInput.type = 'text'; sizeInput.value = styles.fontSize; sizeInput.placeholder = '16px'; sizeInput.style.width = '100%'; sizeInput.style.padding = '6px'; sizeInput.style.border = '1px solid #cbd5e1'; sizeInput.style.borderRadius = '6px'; sizeGroup.appendChild(sizeInput); rewardStyleContainer.appendChild(sizeGroup); section1.appendChild(rewardStyleContainer); // 预览 const previewReward = document.createElement('div'); previewReward.style.marginTop = '8px'; previewReward.style.padding = '8px 12px'; previewReward.style.background = '#f8fafc'; previewReward.style.borderRadius = '6px'; previewReward.style.border = '1px solid #e2e8f0'; previewReward.style.display = 'flex'; previewReward.style.alignItems = 'center'; previewReward.style.gap = '8px'; previewReward.innerHTML = '预览:'; const previewSpan = document.createElement('span'); previewSpan.textContent = '【回帖奖励】示例文本'; previewSpan.style.fontWeight = styles.fontWeight; previewSpan.style.color = styles.color; previewSpan.style.fontSize = styles.fontSize; previewReward.appendChild(previewSpan); section1.appendChild(previewReward); panel.appendChild(section1); // 实时更新预览 const updateRewardPreview = () => { previewSpan.style.fontWeight = weightSelect.value; previewSpan.style.color = colorInput.value; previewSpan.style.fontSize = sizeInput.value; }; weightSelect.addEventListener('change', updateRewardPreview); colorInput.addEventListener('input', updateRewardPreview); sizeInput.addEventListener('input', updateRewardPreview); // ----- 悬赏已解决处理卡片 ----- const section2 = document.createElement('div'); section2.style.marginBottom = '24px'; section2.innerHTML = '

🔍 悬赏已解决处理

'; const actionGroup = document.createElement('div'); actionGroup.style.display = 'flex'; actionGroup.style.gap = '8px'; actionGroup.style.marginBottom = '12px'; const actions = [ { value: 'none', label: '无操作' }, { value: 'mark', label: '标记背景' }, { value: 'hide', label: '隐藏整行' } ]; const radioButtons = []; actions.forEach(act => { const btn = document.createElement('button'); btn.type = 'button'; btn.textContent = act.label; btn.dataset.value = act.value; Object.assign(btn.style, { flex: '1', padding: '8px 0', border: '1px solid #cbd5e1', borderRadius: '20px', background: resolvedAction === act.value ? '#3b82f6' : '#ffffff', color: resolvedAction === act.value ? '#ffffff' : '#334155', fontWeight: resolvedAction === act.value ? '500' : 'normal', cursor: 'pointer', transition: '0.2s' }); btn.addEventListener('click', () => { radioButtons.forEach(b => { b.style.background = '#ffffff'; b.style.color = '#334155'; }); btn.style.background = '#3b82f6'; btn.style.color = '#ffffff'; currentResolvedAction = act.value; }); actionGroup.appendChild(btn); radioButtons.push(btn); }); section2.appendChild(actionGroup); // 背景色选择 const bgGroup = document.createElement('div'); bgGroup.style.display = 'flex'; bgGroup.style.alignItems = 'center'; bgGroup.style.gap = '12px'; bgGroup.style.marginTop = '8px'; bgGroup.innerHTML = '背景色:'; const bgColorInput = document.createElement('input'); bgColorInput.type = 'color'; bgColorInput.value = resolvedBgColor; bgColorInput.style.width = '60px'; bgColorInput.style.height = '34px'; bgColorInput.style.border = '1px solid #cbd5e1'; bgColorInput.style.borderRadius = '6px'; const bgPreview = document.createElement('div'); bgPreview.style.width = '30px'; bgPreview.style.height = '30px'; bgPreview.style.borderRadius = '4px'; bgPreview.style.border = '1px solid #cbd5e1'; bgPreview.style.background = resolvedBgColor; bgGroup.appendChild(bgColorInput); bgGroup.appendChild(bgPreview); section2.appendChild(bgGroup); let currentResolvedAction = resolvedAction; bgColorInput.addEventListener('input', () => { bgPreview.style.background = bgColorInput.value; }); panel.appendChild(section2); // ----- 悬赏金额动态样式卡片 ----- const section3 = document.createElement('div'); section3.style.marginBottom = '24px'; section3.innerHTML = '

💰 悬赏金额动态样式

'; // 启用开关 const enableGroup = document.createElement('div'); enableGroup.style.display = 'flex'; enableGroup.style.alignItems = 'center'; enableGroup.style.gap = '8px'; enableGroup.style.marginBottom = '16px'; const enableCheck = document.createElement('input'); enableCheck.type = 'checkbox'; enableCheck.id = 'rewardEnableCheck'; enableCheck.checked = rewardEnabled; const enableLabel = document.createElement('label'); enableLabel.htmlFor = 'rewardEnableCheck'; enableLabel.textContent = '启用悬赏金额样式'; enableLabel.style.color = '#334155'; enableGroup.appendChild(enableCheck); enableGroup.appendChild(enableLabel); section3.appendChild(enableGroup); // 预设下拉菜单 const presetGroup = document.createElement('div'); presetGroup.style.display = 'flex'; presetGroup.style.alignItems = 'center'; presetGroup.style.gap = '8px'; presetGroup.style.marginBottom = '12px'; presetGroup.innerHTML = '预设样式:'; const presetSelect = document.createElement('select'); presetSelect.style.padding = '6px'; presetSelect.style.border = '1px solid #cbd5e1'; presetSelect.style.borderRadius = '6px'; presetSelect.innerHTML = ` `; presetGroup.appendChild(presetSelect); const applyPresetBtn = document.createElement('button'); applyPresetBtn.textContent = '应用预设'; applyPresetBtn.style.padding = '6px 12px'; applyPresetBtn.style.background = '#e2e8f0'; applyPresetBtn.style.border = '1px solid #cbd5e1'; applyPresetBtn.style.borderRadius = '6px'; applyPresetBtn.style.cursor = 'pointer'; presetGroup.appendChild(applyPresetBtn); section3.appendChild(presetGroup); // 规则表格 const table = document.createElement('table'); table.style.width = '100%'; table.style.borderCollapse = 'collapse'; table.style.fontSize = '13px'; table.innerHTML = ` 最低 最高 颜色 加粗 背景色 字号 预览 `; const tbody = table.querySelector('#rulesTbody'); section3.appendChild(table); // 添加规则按钮 const addBtn = document.createElement('button'); addBtn.textContent = '+ 添加规则'; Object.assign(addBtn.style, { marginTop: '8px', padding: '6px 12px', background: '#e2e8f0', border: '1px solid #cbd5e1', borderRadius: '6px', cursor: 'pointer', color: '#1e293b' }); section3.appendChild(addBtn); panel.appendChild(section3); // ----- 按钮组 ----- const btnGroup = document.createElement('div'); btnGroup.style.display = 'flex'; btnGroup.style.justifyContent = 'flex-end'; btnGroup.style.gap = '10px'; btnGroup.style.marginTop = '20px'; btnGroup.style.borderTop = '1px solid #e2e8f0'; btnGroup.style.paddingTop = '16px'; const resetBtn = document.createElement('button'); resetBtn.textContent = '重置默认'; resetBtn.style.padding = '8px 16px'; resetBtn.style.background = '#f1f5f9'; resetBtn.style.border = '1px solid #cbd5e1'; resetBtn.style.borderRadius = '6px'; resetBtn.style.cursor = 'pointer'; const applyBtn = document.createElement('button'); applyBtn.textContent = '应用'; applyBtn.style.padding = '8px 20px'; applyBtn.style.background = '#3b82f6'; applyBtn.style.border = 'none'; applyBtn.style.borderRadius = '6px'; applyBtn.style.color = 'white'; applyBtn.style.cursor = 'pointer'; const saveBtn = document.createElement('button'); saveBtn.textContent = '保存并关闭'; saveBtn.style.padding = '8px 20px'; saveBtn.style.background = '#1e293b'; saveBtn.style.border = 'none'; saveBtn.style.borderRadius = '6px'; saveBtn.style.color = 'white'; saveBtn.style.cursor = 'pointer'; const cancelBtn = document.createElement('button'); cancelBtn.textContent = '关闭'; cancelBtn.style.padding = '8px 16px'; cancelBtn.style.background = '#ef4444'; cancelBtn.style.border = 'none'; cancelBtn.style.borderRadius = '6px'; cancelBtn.style.color = 'white'; cancelBtn.style.cursor = 'pointer'; btnGroup.appendChild(resetBtn); btnGroup.appendChild(applyBtn); btnGroup.appendChild(saveBtn); btnGroup.appendChild(cancelBtn); panel.appendChild(btnGroup); document.body.appendChild(panel); settingsPanel = panel; // ---------- 辅助函数:创建规则行(带预览) ---------- function createRuleRow(rule = { min: 1, max: null, style: { color: '#000000', fontWeight: 'normal', backgroundColor: '#ffffff', fontSize: '' } }) { const tr = document.createElement('tr'); tr.style.borderBottom = '1px solid #e2e8f0'; // 最低 const tdMin = document.createElement('td'); const minInput = document.createElement('input'); minInput.type = 'number'; minInput.value = rule.min; minInput.style.width = '60px'; minInput.style.padding = '4px'; minInput.style.border = '1px solid #cbd5e1'; minInput.style.borderRadius = '4px'; tdMin.appendChild(minInput); tr.appendChild(tdMin); // 最高 const tdMax = document.createElement('td'); const maxInput = document.createElement('input'); maxInput.type = 'number'; maxInput.value = rule.max !== null ? rule.max : ''; maxInput.placeholder = '无上限'; maxInput.style.width = '60px'; maxInput.style.padding = '4px'; maxInput.style.border = '1px solid #cbd5e1'; maxInput.style.borderRadius = '4px'; tdMax.appendChild(maxInput); tr.appendChild(tdMax); // 颜色 const tdColor = document.createElement('td'); const colorPicker = document.createElement('input'); colorPicker.type = 'color'; colorPicker.value = rule.style.color || '#000000'; colorPicker.style.width = '40px'; colorPicker.style.height = '30px'; colorPicker.style.border = 'none'; tdColor.appendChild(colorPicker); tr.appendChild(tdColor); // 加粗 const tdBold = document.createElement('td'); tdBold.style.textAlign = 'center'; const boldCheck = document.createElement('input'); boldCheck.type = 'checkbox'; boldCheck.checked = rule.style.fontWeight === 'bold'; tdBold.appendChild(boldCheck); tr.appendChild(tdBold); // 背景色 const tdBg = document.createElement('td'); const bgPicker = document.createElement('input'); bgPicker.type = 'color'; bgPicker.value = rule.style.backgroundColor || '#ffffff'; bgPicker.style.width = '40px'; bgPicker.style.height = '30px'; bgPicker.style.border = 'none'; tdBg.appendChild(bgPicker); tr.appendChild(tdBg); // 字号 const tdSize = document.createElement('td'); const sizeInput = document.createElement('input'); sizeInput.type = 'text'; sizeInput.value = rule.style.fontSize || ''; sizeInput.placeholder = '14px'; sizeInput.style.width = '50px'; sizeInput.style.padding = '4px'; sizeInput.style.border = '1px solid #cbd5e1'; sizeInput.style.borderRadius = '4px'; tdSize.appendChild(sizeInput); tr.appendChild(tdSize); // 预览单元格 const tdPreview = document.createElement('td'); const previewSpan = document.createElement('span'); previewSpan.textContent = '预览'; previewSpan.style.padding = '2px 6px'; previewSpan.style.borderRadius = '4px'; previewSpan.style.color = rule.style.color || '#000000'; previewSpan.style.fontWeight = rule.style.fontWeight || 'normal'; previewSpan.style.backgroundColor = rule.style.backgroundColor || 'transparent'; previewSpan.style.fontSize = rule.style.fontSize || 'inherit'; tdPreview.appendChild(previewSpan); tr.appendChild(tdPreview); // 删除按钮 const tdDel = document.createElement('td'); const delBtn = document.createElement('button'); delBtn.textContent = '✕'; delBtn.style.background = 'none'; delBtn.style.border = 'none'; delBtn.style.color = '#ef4444'; delBtn.style.fontSize = '16px'; delBtn.style.cursor = 'pointer'; delBtn.onclick = () => tr.remove(); tdDel.appendChild(delBtn); tr.appendChild(tdDel); // 实时更新预览 function updatePreview() { previewSpan.style.color = colorPicker.value; previewSpan.style.fontWeight = boldCheck.checked ? 'bold' : 'normal'; previewSpan.style.backgroundColor = bgPicker.value === '#ffffff' ? 'transparent' : bgPicker.value; previewSpan.style.fontSize = sizeInput.value || 'inherit'; } colorPicker.addEventListener('input', updatePreview); boldCheck.addEventListener('change', updatePreview); bgPicker.addEventListener('input', updatePreview); sizeInput.addEventListener('input', updatePreview); minInput.addEventListener('input', updatePreview); // 虽然不影响预览,但为了统一 maxInput.addEventListener('input', updatePreview); return tr; } // 填充现有规则 function loadRulesToTable(rules) { tbody.innerHTML = ''; rules.forEach(rule => { tbody.appendChild(createRuleRow(rule)); }); } loadRulesToTable(rewardRules); // 应用预设 applyPresetBtn.addEventListener('click', () => { const presetName = presetSelect.value; loadRulesToTable(presets[presetName]); }); // 添加规则 addBtn.addEventListener('click', () => { tbody.appendChild(createRuleRow()); }); // 重置默认 resetBtn.addEventListener('click', () => { loadRulesToTable(defaultRewardRules); }); // ---------- 保存功能 ---------- function saveSettings(closeAfterSave = false) { // 回帖奖励样式 styles.fontWeight = weightSelect.value; styles.color = colorInput.value; styles.fontSize = sizeInput.value; GM_setValue('fontWeight', styles.fontWeight); GM_setValue('color', styles.color); GM_setValue('fontSize', styles.fontSize); // 悬赏已解决 resolvedAction = currentResolvedAction; GM_setValue('resolvedAction', resolvedAction); resolvedBgColor = bgColorInput.value; GM_setValue('resolvedBgColor', resolvedBgColor); // 悬赏金额 rewardEnabled = enableCheck.checked; GM_setValue(REWARD_ENABLED_KEY, rewardEnabled); // 从表格构建规则 const newRules = []; for (const row of tbody.children) { const inputs = row.querySelectorAll('input'); const min = parseInt(inputs[0].value); if (isNaN(min)) continue; const max = inputs[1].value ? parseInt(inputs[1].value) : null; const color = inputs[2].value; const bold = inputs[3].checked; const bg = inputs[4].value; const fontSize = inputs[5].value; const style = { color: color, fontWeight: bold ? 'bold' : 'normal', }; if (bg && bg !== '#ffffff') style.backgroundColor = bg; if (fontSize) style.fontSize = fontSize; newRules.push({ min, max, style }); } rewardRules = newRules; GM_setValue(REWARD_RULES_KEY, rewardRules); // 立即应用 checkAndModify(); if (closeAfterSave) { panel.style.display = 'none'; } else { const savedTip = document.createElement('div'); savedTip.textContent = '✓ 已应用'; Object.assign(savedTip.style, { position: 'fixed', bottom: '20px', right: '20px', background: '#10b981', color: 'white', padding: '8px 16px', borderRadius: '20px', boxShadow: '0 2px 8px rgba(0,0,0,0.2)', zIndex: '10000' }); document.body.appendChild(savedTip); setTimeout(() => savedTip.remove(), 1500); } } applyBtn.addEventListener('click', () => saveSettings(false)); saveBtn.addEventListener('click', () => saveSettings(true)); cancelBtn.addEventListener('click', () => panel.style.display = 'none'); } // ---------- 注册菜单命令 ---------- GM_registerMenuCommand("⚙️ 打开设置面板", createSettingsPanel); // ---------- 启动核心功能 ---------- const observer = new MutationObserver(checkAndModify); observer.observe(document.body, { childList: true, subtree: true }); checkAndModify(); setInterval(checkAndModify, 1000); })();