BRTHZKTRVUWM2HJQESST25FC4TREZ3LGB7UESDGUT5KF2NKJ5GGAC // 知乎屏蔽词 - 选项页面脚本(function () {'use strict';const input = document.getElementById('keyword-input');const addBtn = document.getElementById('add-btn');const listEl = document.getElementById('keyword-list');const countEl = document.getElementById('count');const statusEl = document.getElementById('status');let keywords = [];// 加载屏蔽词列表async function loadKeywords() {const result = await browser.storage.local.get('blockKeywords');keywords = result.blockKeywords || [];renderList();}// 保存屏蔽词列表async function saveKeywords() {await browser.storage.local.set({ blockKeywords: keywords });}// 渲染列表function renderList() {countEl.textContent = `共 ${keywords.length} 个屏蔽词`;listEl.textContent = '';if (keywords.length === 0) {const tip = document.createElement('div');tip.className = 'empty-tip';tip.textContent = '暂无屏蔽词';listEl.appendChild(tip);return;}keywords.forEach((kw, index) => {const item = document.createElement('div');item.className = 'keyword-item';const span = document.createElement('span');span.className = 'keyword-text';span.textContent = kw;const btn = document.createElement('button');btn.className = 'delete-btn';btn.dataset.index = index;btn.textContent = '删除';item.appendChild(span);item.appendChild(btn);listEl.appendChild(item);});}// 显示状态消息function showStatus(message, isError = false) {statusEl.textContent = message;statusEl.className = 'status ' + (isError ? 'error' : 'success');setTimeout(() => {statusEl.className = 'status';}, 2000);}// 添加屏蔽词async function addKeyword() {const keyword = input.value.trim();if (!keyword) {showStatus('请输入关键词', true);return;}if (keywords.includes(keyword)) {showStatus('该关键词已存在', true);return;}keywords.push(keyword);await saveKeywords();renderList();input.value = '';showStatus('添加成功');}// 删除屏蔽词async function deleteKeyword(index) {keywords.splice(index, 1);await saveKeywords();renderList();showStatus('删除成功');}// 导入屏蔽词function importKeywords(file) {const reader = new FileReader();reader.onload = async function (e) {const text = e.target.result.trim();let incoming = [];try {const parsed = JSON.parse(text);if (Array.isArray(parsed)) {incoming = parsed.map(String).map(s => s.trim()).filter(Boolean);} else {showStatus('JSON 格式错误:需要数组', true);return;}} catch {// 非 JSON,按纯文本处理(每行一个关键词)incoming = text.split('\n').map(s => s.trim()).filter(Boolean);}const existingSet = new Set(keywords);const newWords = incoming.filter(w => !existingSet.has(w));keywords.push(...newWords);await saveKeywords();renderList();showStatus(`导入完成,新增 ${newWords.length} 个屏蔽词`);};reader.readAsText(file);}// 导出屏蔽词function exportKeywords() {const blob = new Blob([JSON.stringify(keywords, null, 2)], { type: 'application/json' });const url = URL.createObjectURL(blob);const a = document.createElement('a');a.href = url;a.download = 'blocked_keywords.json';a.click();URL.revokeObjectURL(url);}// 事件监听const importBtn = document.getElementById('import-btn');const exportBtn = document.getElementById('export-btn');const importFile = document.getElementById('import-file');importBtn.addEventListener('click', () => importFile.click());importFile.addEventListener('change', (e) => {if (e.target.files.length > 0) {importKeywords(e.target.files[0]);e.target.value = '';}});exportBtn.addEventListener('click', exportKeywords);addBtn.addEventListener('click', addKeyword);input.addEventListener('keypress', (e) => {if (e.key === 'Enter') {addKeyword();}});listEl.addEventListener('click', (e) => {if (e.target.classList.contains('delete-btn')) {const index = parseInt(e.target.dataset.index, 10);deleteKeyword(index);}});// 初始化loadKeywords();})();
<!DOCTYPE html><html lang="zh-CN"><head><meta charset="UTF-8"><title>知乎屏蔽词设置</title><style>* {box-sizing: border-box;}body {font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;padding: 16px;min-width: 400px;background: #f6f6f6;margin: 0;}h1 {font-size: 18px;margin: 0 0 16px 0;color: #1a1a1a;}.input-group {display: flex;gap: 8px;margin-bottom: 16px;}#keyword-input {flex: 1;padding: 8px 12px;border: 1px solid #d9d9d9;border-radius: 4px;font-size: 14px;}#keyword-input:focus {outline: none;border-color: #0066ff;}button {padding: 8px 16px;background: #0066ff;color: white;border: none;border-radius: 4px;cursor: pointer;font-size: 14px;}button:hover {background: #0052cc;}.keyword-list {background: white;border: 1px solid #d9d9d9;border-radius: 4px;max-height: 300px;overflow-y: auto;}.keyword-item {display: flex;justify-content: space-between;align-items: center;padding: 10px 12px;border-bottom: 1px solid #f0f0f0;}.keyword-item:last-child {border-bottom: none;}.keyword-text {font-size: 14px;color: #1a1a1a;word-break: break-all;}.delete-btn {padding: 4px 8px;background: #ff4d4f;font-size: 12px;}.delete-btn:hover {background: #ff7875;}.empty-tip {padding: 24px;text-align: center;color: #8c8c8c;font-size: 14px;}.status {margin-top: 12px;padding: 8px;border-radius: 4px;font-size: 13px;display: none;}.status.success {display: block;background: #f6ffed;color: #52c41a;border: 1px solid #b7eb8f;}.status.error {display: block;background: #fff2f0;color: #ff4d4f;border: 1px solid #ffccc7;}.count {font-size: 13px;color: #8c8c8c;margin-bottom: 8px;}.action-group {display: flex;gap: 8px;margin-bottom: 16px;}.action-group button {padding: 6px 14px;font-size: 13px;}.import-btn {background: #52c41a;}.import-btn:hover {background: #389e0d;}.export-btn {background: #666;}.export-btn:hover {background: #555;}</style></head><body><h1>屏蔽词管理</h1><div class="input-group"><input type="text" id="keyword-input" placeholder="输入要屏蔽的关键词"><button id="add-btn">添加</button></div><div class="action-group"><button class="import-btn" id="import-btn">导入</button><button class="export-btn" id="export-btn">导出</button><input type="file" id="import-file" accept=".json,.txt" style="display:none"></div><div class="count" id="count"></div><div class="keyword-list" id="keyword-list"><div class="empty-tip">暂无屏蔽词</div></div><div class="status" id="status"></div><script src="options.js"></script></body></html>
{"manifest_version": 3,"name": "知乎屏蔽词","version": "1.0.0","description": "根据关键词屏蔽知乎内容","homepage_url": "https://nest.pijul.com/DzmingLi/zhihu-filter","browser_specific_settings": {"gecko": {"id": "zhihu-filter@dzming.li","data_collection_permissions": {"required": ["none"]}}},"permissions": ["storage"],"options_ui": {"page": "options.html","open_in_tab": false},"content_scripts": [{"matches": ["https://www.zhihu.com/*","https://zhihu.com/*"],"js": ["content.js"],"run_at": "document_idle"}]}
// 知乎屏蔽词 - 内容脚本(function () {'use strict';const CONTAINER_SELECTOR = '.ContentItem';const TITLE_SELECTOR = '.ContentItem-title a';const EXCERPT_SELECTOR = '.RichText.ztext';let blockKeywords = [];function processElement(el) {if (el.dataset.blocked) return;if (blockKeywords.length === 0) return;const title = el.querySelector(TITLE_SELECTOR)?.textContent?.trim() || '';const excerpt = el.querySelector(EXCERPT_SELECTOR)?.textContent?.trim() || '';const text = title + ' ' + excerpt;const matched = blockKeywords.find(k => k && text.includes(k));if (matched) {el.style.display = 'none';el.dataset.blocked = '1';console.log(`[知乎屏蔽词] 已屏蔽关键词「${matched}」→ ${title || excerpt.slice(0, 50)}`);}}function processAll() {document.querySelectorAll(CONTAINER_SELECTOR).forEach(processElement);}// 加载屏蔽词并开始处理async function init() {const result = await browser.storage.local.get('blockKeywords');blockKeywords = result.blockKeywords || [];// 监听存储变化,实时更新屏蔽词browser.storage.onChanged.addListener((changes, area) => {if (area === 'local' && changes.blockKeywords) {blockKeywords = changes.blockKeywords.newValue || [];// 重新处理页面(清除已处理标记)document.querySelectorAll(CONTAINER_SELECTOR).forEach(el => {delete el.dataset.blocked;el.style.display = '';});processAll();}});// 监听动态加载new MutationObserver(mutations => {mutations.forEach(m => {m.addedNodes.forEach(node => {if (node.nodeType !== 1) return;if (node.matches?.(CONTAINER_SELECTOR)) {processElement(node);} else {node.querySelectorAll?.(CONTAINER_SELECTOR).forEach(processElement);}});});}).observe(document.body, { childList: true, subtree: true });processAll();}init();})();