// ==UserScript==
// @name 智能搜索结果屏蔽工具(带图形界面)
// @namespace http://tampermonkey.net/
// @version 2.1
// @description 带图形界面的搜索结果屏蔽工具,可自定义屏蔽规则
// @author DeepSeek AI & 镰刀(只是当甲方,贡献都是AI的)
// @match *://www.baidu.com/*
// @match *://www.bing.com/*
// @match *://*.google.com/*
// @grant GM_addStyle
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_registerMenuCommand
// @icon https://img.icons8.com/fluency/48/block.png
// @license MIT
// ==/UserScript==
(function() {
'use strict';
// 加载保存的规则
const loadRules = () => {
const savedRules = GM_getValue('blockRules', null);
return savedRules || [
{
id: Date.now(),
keywords: ['吧友互助'],
domains: ['*.baidu.com', '*.tieba.baidu.com', 'tieba.com'],
note: '屏蔽百度贴吧吧友互助内容',
enabled: true
}
];
};
// 保存规则
const saveRules = (rules) => {
GM_setValue('blockRules', rules);
};
// 主屏蔽函数
function blockResults() {
const rules = loadRules().filter(rule => rule.enabled);
// 获取所有搜索结果项(适配不同搜索引擎)
const items = getSearchResultItems();
items.forEach(item => {
// 检查是否匹配任何屏蔽规则
const shouldBlock = rules.some(rule =>
matchRule(item, rule.keywords, rule.domains)
);
if (shouldBlock) {
item.style.display = 'none';
}
});
}
// 获取搜索结果项(兼容不同搜索引擎)
function getSearchResultItems() {
// 百度
if (window.location.host.includes('baidu')) {
return Array.from(document.querySelectorAll('.c-container, .result'));
}
// Bing
else if (window.location.host.includes('bing')) {
return Array.from(document.querySelectorAll('.b_algo, .b_algoGroup'));
}
// Google
else if (window.location.host.includes('google')) {
return Array.from(document.querySelectorAll('.g, .tF2Cxc'));
}
// 默认选择器
return Array.from(document.querySelectorAll('li, .result'));
}
// 检查元素是否匹配规则
function matchRule(element, keywords, domains) {
const textContent = element.textContent.toLowerCase();
// 检查是否包含关键词
const hasKeyword = keywords.some(keyword =>
keyword && textContent.includes(keyword.toLowerCase())
);
// 如果关键词不匹配,直接返回false
if (!hasKeyword) return false;
// 检查是否包含目标域名
const links = element.querySelectorAll('a');
for (const link of links) {
const href = link.href.toLowerCase();
const matched = domains.some(domain => {
// 处理通配符
if (domain.startsWith('*.')) {
const baseDomain = domain.substring(2);
return href.includes(baseDomain);
}
return href.includes(domain);
});
if (matched) return true;
}
return false;
}
// 创建控制面板
function createControlPanel() {
// 创建主容器
const panel = document.createElement('div');
panel.id = 'blocker-panel';
panel.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
width: 380px;
background: rgba(25, 25, 40, 0.98);
border-radius: 16px;
padding: 20px;
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.5);
backdrop-filter: blur(12px);
border: 1px solid rgba(255, 255, 255, 0.12);
color: #f0f0f0;
font-family: 'Segoe UI', system-ui, sans-serif;
z-index: 10000;
max-height: 85vh;
overflow: hidden;
display: flex;
flex-direction: column;
transition: transform 0.3s ease, opacity 0.3s ease;
transform: translateY(0);
opacity: 1;
`;
// 标题栏
const header = document.createElement('div');
header.style.cssText = `
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20px;
padding-bottom: 15px;
border-bottom: 1px solid rgba(255, 255, 255, 0.15);
`;
const title = document.createElement('div');
title.style.cssText = `
display: flex;
align-items: center;
gap: 12px;
`;
const icon = document.createElement('div');
icon.innerHTML = '🔍';
icon.style.cssText = `
width: 36px;
height: 36px;
background: linear-gradient(135deg, #ff8a00, #da1b60);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
font-size: 18px;
`;
const titleText = document.createElement('div');
titleText.innerHTML = `
<div style="font-size: 1.4rem; font-weight: 700; color: #ff8a00;">搜索结果屏蔽工具</div>
<div style="font-size: 0.9rem; color: #a0a0c0;">添加/管理屏蔽规则</div>
`;
title.appendChild(icon);
title.appendChild(titleText);
const closeBtn = document.createElement('button');
closeBtn.textContent = '×';
closeBtn.style.cssText = `
background: rgba(255, 255, 255, 0.1);
border: none;
color: #aaa;
font-size: 1.6rem;
cursor: pointer;
width: 36px;
height: 36px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
transition: all 0.2s ease;
`;
closeBtn.addEventListener('mouseover', () => {
closeBtn.style.background = 'rgba(218, 27, 96, 0.3)';
closeBtn.style.color = '#ff5577';
});
closeBtn.addEventListener('mouseout', () => {
closeBtn.style.background = 'rgba(255, 255, 255, 0.1)';
closeBtn.style.color = '#aaa';
});
closeBtn.addEventListener('click', () => {
panel.style.transform = 'translateY(20px)';
panel.style.opacity = '0';
setTimeout(() => panel.style.display = 'none', 300);
});
header.appendChild(title);
header.appendChild(closeBtn);
panel.appendChild(header);
// 规则表单
const form = document.createElement('div');
form.style.marginBottom = '25px';
form.style.padding = '15px';
form.style.background = 'rgba(0, 0, 0, 0.25)';
form.style.borderRadius = '12px';
const formTitle = document.createElement('div');
formTitle.textContent = '添加新规则';
formTitle.style.cssText = `
margin: 0 0 18px 0;
font-size: 1.15rem;
font-weight: 600;
color: #4df;
display: flex;
align-items: center;
gap: 8px;
`;
formTitle.innerHTML = '<span style="font-size:1.2em">➕</span> 添加新规则';
form.appendChild(formTitle);
// 关键词输入
const keywordGroup = document.createElement('div');
keywordGroup.style.marginBottom = '18px';
const keywordLabel = document.createElement('div');
keywordLabel.textContent = '关键词(用逗号分隔)';
keywordLabel.style.cssText = `
margin-bottom: 8px;
font-size: 0.95rem;
color: #a0a0c0;
display: flex;
align-items: center;
gap: 6px;
`;
keywordLabel.innerHTML = '🔤 关键词(用逗号分隔)';
const keywordInput = document.createElement('input');
keywordInput.type = 'text';
keywordInput.placeholder = '例如: 吧友互助,广告,推广';
keywordInput.style.cssText = `
width: 100%;
padding: 12px 15px;
border-radius: 10px;
border: 1px solid rgba(255, 255, 255, 0.15);
background: rgba(40, 40, 60, 0.8);
color: white;
font-size: 0.95rem;
transition: border 0.2s ease;
`;
keywordGroup.appendChild(keywordLabel);
keywordGroup.appendChild(keywordInput);
form.appendChild(keywordGroup);
// 域名输入
const domainGroup = document.createElement('div');
domainGroup.style.marginBottom = '18px';
const domainLabel = document.createElement('div');
domainLabel.textContent = '域名(用逗号分隔,支持通配符)';
domainLabel.style.cssText = keywordLabel.style.cssText;
domainLabel.innerHTML = '🌐 域名(用逗号分隔,支持通配符)';
const domainInput = document.createElement('input');
domainInput.type = 'text';
domainInput.placeholder = '例如: *.baidu.com, tieba.com, *.example.com';
domainInput.style.cssText = keywordInput.style.cssText;
domainGroup.appendChild(domainLabel);
domainGroup.appendChild(domainInput);
form.appendChild(domainGroup);
// 备注输入
const noteGroup = document.createElement('div');
noteGroup.style.marginBottom = '20px';
const noteLabel = document.createElement('div');
noteLabel.textContent = '规则备注(可选)';
noteLabel.style.cssText = keywordLabel.style.cssText;
noteLabel.innerHTML = '📝 规则备注(可选)';
const noteInput = document.createElement('input');
noteInput.type = 'text';
noteInput.placeholder = '例如: 屏蔽百度贴吧内容';
noteInput.style.cssText = keywordInput.style.cssText;
noteGroup.appendChild(noteLabel);
noteGroup.appendChild(noteInput);
form.appendChild(noteGroup);
// 添加按钮
const addBtn = document.createElement('button');
addBtn.textContent = '添加屏蔽规则';
addBtn.style.cssText = `
background: linear-gradient(135deg, #ff8a00, #da1b60);
color: white;
border: none;
padding: 13px 20px;
border-radius: 10px;
cursor: pointer;
font-size: 1rem;
font-weight: 600;
width: 100%;
transition: all 0.3s ease;
display: flex;
justify-content: center;
align-items: center;
gap: 8px;
`;
addBtn.innerHTML = '🚫 添加屏蔽规则';
addBtn.addEventListener('mouseover', () => {
addBtn.style.transform = 'translateY(-2px)';
addBtn.style.boxShadow = '0 8px 20px rgba(218, 27, 96, 0.5)';
});
addBtn.addEventListener('mouseout', () => {
addBtn.style.transform = 'none';
addBtn.style.boxShadow = 'none';
});
addBtn.addEventListener('click', () => {
const keywords = keywordInput.value.split(',').map(k => k.trim()).filter(k => k);
const domains = domainInput.value.split(',').map(d => d.trim()).filter(d => d);
const note = noteInput.value.trim();
if (keywords.length === 0 || domains.length === 0) {
showNotification('请输入关键词和域名', 'warning');
return;
}
const newRule = {
id: Date.now(),
keywords,
domains,
note: note || '未命名规则',
enabled: true
};
const rules = loadRules();
rules.push(newRule);
saveRules(rules);
// 重置表单
keywordInput.value = '';
domainInput.value = '';
noteInput.value = '';
// 刷新规则列表
renderRulesList();
// 重新应用屏蔽
blockResults();
showNotification('规则添加成功!', 'success');
});
form.appendChild(addBtn);
panel.appendChild(form);
// 规则列表
const rulesListContainer = document.createElement('div');
rulesListContainer.style.cssText = `
flex: 1;
overflow-y: auto;
border-top: 1px solid rgba(255, 255, 255, 0.15);
padding-top: 18px;
`;
const rulesTitle = document.createElement('div');
rulesTitle.style.cssText = formTitle.style.cssText;
rulesTitle.innerHTML = '<span style="font-size:1.2em">📋</span> 当前规则';
rulesListContainer.appendChild(rulesTitle);
const rulesList = document.createElement('div');
rulesList.id = 'blocker-rules-list';
rulesList.style.cssText = `
max-height: 320px;
overflow-y: auto;
margin-top: 12px;
`;
rulesListContainer.appendChild(rulesList);
panel.appendChild(rulesListContainer);
// 渲染规则列表
function renderRulesList() {
const rules = loadRules();
rulesList.innerHTML = '';
if (rules.length === 0) {
const emptyMsg = document.createElement('div');
emptyMsg.textContent = '没有添加任何规则';
emptyMsg.style.cssText = `
text-align: center;
padding: 30px 20px;
color: #777;
font-style: italic;
`;
rulesList.appendChild(emptyMsg);
return;
}
rules.forEach(rule => {
const ruleEl = document.createElement('div');
ruleEl.style.cssText = `
background: linear-gradient(to right, rgba(50, 50, 70, 0.6), rgba(40, 40, 60, 0.7));
border-radius: 12px;
padding: 16px;
margin-bottom: 14px;
position: relative;
border-left: 4px solid ${rule.enabled ? '#ff8a00' : '#555'};
transition: all 0.2s ease;
`;
const title = document.createElement('div');
title.style.cssText = `
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
`;
const ruleTitle = document.createElement('div');
ruleTitle.style.cssText = `
font-weight: 600;
font-size: 1.05rem;
color: ${rule.enabled ? '#ffaa44' : '#888'};
max-width: 70%;
`;
ruleTitle.textContent = rule.note;
const toggle = document.createElement('div');
toggle.style.cssText = `
display: flex;
align-items: center;
gap: 8px;
`;
const toggleLabel = document.createElement('span');
toggleLabel.textContent = rule.enabled ? '启用中' : '已禁用';
toggleLabel.style.cssText = `
font-size: 0.85rem;
color: ${rule.enabled ? '#4df' : '#888'};
`;
const toggleSwitch = document.createElement('label');
toggleSwitch.style.cssText = `
position: relative;
display: inline-block;
width: 44px;
height: 24px;
`;
const toggleInput = document.createElement('input');
toggleInput.type = 'checkbox';
toggleInput.checked = rule.enabled;
toggleInput.style.cssText = `
opacity: 0;
width: 0;
height: 0;
`;
const toggleSlider = document.createElement('span');
toggleSlider.style.cssText = `
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: ${rule.enabled ? 'rgba(255, 138, 0, 0.3)' : '#555'};
transition: .4s;
border-radius: 24px;
`;
const toggleKnob = document.createElement('span');
toggleKnob.style.cssText = `
position: absolute;
content: "";
height: 18px;
width: 18px;
left: 3px;
bottom: 3px;
background-color: ${rule.enabled ? '#ff8a00' : '#aaa'};
transition: .4s;
border-radius: 50%;
box-shadow: 0 2px 4px rgba(0,0,0,0.2);
`;
toggleInput.addEventListener('change', () => {
rule.enabled = toggleInput.checked;
saveRules(rules);
ruleEl.style.borderLeftColor = rule.enabled ? '#ff8a00' : '#555';
ruleTitle.style.color = rule.enabled ? '#ffaa44' : '#888';
toggleLabel.textContent = rule.enabled ? '启用中' : '已禁用';
toggleLabel.style.color = rule.enabled ? '#4df' : '#888';
toggleKnob.style.backgroundColor = rule.enabled ? '#ff8a00' : '#aaa';
toggleSlider.style.backgroundColor = rule.enabled ? 'rgba(255, 138, 0, 0.3)' : '#555';
blockResults();
});
toggleSwitch.appendChild(toggleInput);
toggleSwitch.appendChild(toggleSlider);
toggleSwitch.appendChild(toggleKnob);
toggle.appendChild(toggleLabel);
toggle.appendChild(toggleSwitch);
title.appendChild(ruleTitle);
title.appendChild(toggle);
ruleEl.appendChild(title);
const keywords = document.createElement('div');
keywords.textContent = `关键词: ${rule.keywords.join(', ')}`;
keywords.style.cssText = `
font-size: 0.9rem;
margin-bottom: 8px;
color: #ddd;
padding: 8px;
background: rgba(0, 0, 0, 0.2);
border-radius: 6px;
`;
ruleEl.appendChild(keywords);
const domains = document.createElement('div');
domains.textContent = `域名: ${rule.domains.join(', ')}`;
domains.style.cssText = keywords.style.cssText;
ruleEl.appendChild(domains);
const deleteBtn = document.createElement('button');
deleteBtn.textContent = '删除规则';
deleteBtn.style.cssText = `
position: absolute;
bottom: 16px;
right: 16px;
background: rgba(218, 27, 96, 0.2);
color: #ff5577;
border: none;
padding: 6px 12px;
border-radius: 6px;
cursor: pointer;
font-size: 0.85rem;
display: flex;
align-items: center;
gap: 5px;
transition: all 0.2s ease;
`;
deleteBtn.innerHTML = '🗑️ 删除规则';
deleteBtn.addEventListener('mouseover', () => {
deleteBtn.style.background = 'rgba(218, 27, 96, 0.3)';
deleteBtn.style.color = '#ff7788';
});
deleteBtn.addEventListener('mouseout', () => {
deleteBtn.style.background = 'rgba(218, 27, 96, 0.2)';
deleteBtn.style.color = '#ff5577';
});
deleteBtn.addEventListener('click', () => {
if (confirm('确定要删除这条规则吗?')) {
const newRules = rules.filter(r => r.id !== rule.id);
saveRules(newRules);
renderRulesList();
blockResults();
showNotification('规则已删除', 'info');
}
});
ruleEl.appendChild(deleteBtn);
rulesList.appendChild(ruleEl);
});
}
// 初始渲染规则列表
renderRulesList();
// 添加面板到页面
document.body.appendChild(panel);
// 添加拖动功能
let isDragging = false;
let offsetX, offsetY;
header.addEventListener('mousedown', (e) => {
if (e.target === closeBtn) return;
isDragging = true;
offsetX = e.clientX - panel.getBoundingClientRect().left;
offsetY = e.clientY - panel.getBoundingClientRect().top;
panel.style.cursor = 'grabbing';
});
document.addEventListener('mousemove', (e) => {
if (!isDragging) return;
const x = e.clientX - offsetX;
const y = e.clientY - offsetY;
// 限制在窗口范围内
const maxX = window.innerWidth - panel.offsetWidth;
const maxY = window.innerHeight - panel.offsetHeight;
panel.style.left = `${Math.max(0, Math.min(x, maxX))}px`;
panel.style.top = `${Math.max(0, Math.min(y, maxY))}px`;
});
document.addEventListener('mouseup', () => {
isDragging = false;
panel.style.cursor = '';
});
return panel;
}
// 显示通知
function showNotification(message, type = 'info') {
const notification = document.createElement('div');
notification.style.cssText = `
position: fixed;
bottom: 20px;
right: 20px;
background: ${type === 'success' ? 'rgba(40, 167, 69, 0.9)' :
type === 'warning' ? 'rgba(255, 193, 7, 0.9)' :
type === 'error' ? 'rgba(220, 53, 69, 0.9)' : 'rgba(40, 40, 60, 0.9)'};
color: white;
padding: 14px 22px;
border-radius: 10px;
font-family: Arial, sans-serif;
font-size: 14px;
z-index: 9998;
box-shadow: 0 6px 15px rgba(0, 0, 0, 0.3);
backdrop-filter: blur(5px);
max-width: 300px;
display: flex;
align-items: center;
gap: 12px;
transform: translateY(20px);
opacity: 0;
transition: transform 0.3s ease, opacity 0.3s ease;
`;
const icon = document.createElement('div');
icon.style.cssText = `
font-size: 1.4rem;
`;
icon.textContent = type === 'success' ? '✅' :
type === 'warning' ? '⚠️' :
type === 'error' ? '❌' : 'ℹ️';
const text = document.createElement('div');
text.textContent = message;
notification.appendChild(icon);
notification.appendChild(text);
document.body.appendChild(notification);
// 显示动画
setTimeout(() => {
notification.style.transform = 'translateY(0)';
notification.style.opacity = '1';
}, 10);
// 3秒后淡出
setTimeout(() => {
notification.style.transform = 'translateY(20px)';
notification.style.opacity = '0';
setTimeout(() => notification.remove(), 300);
}, 3000);
}
// 添加控制按钮
function addControlButton() {
const button = document.createElement('button');
button.id = 'blocker-control-btn';
button.style.cssText = `
position: fixed;
bottom: 30px;
right: 30px;
width: 60px;
height: 60px;
border-radius: 50%;
background: linear-gradient(135deg, #ff8a00, #da1b60);
color: white;
border: none;
cursor: pointer;
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.4);
z-index: 9999;
display: flex;
align-items: center;
justify-content: center;
font-size: 1.8rem;
transition: all 0.3s ease;
`;
button.innerHTML = '🔍';
button.addEventListener('mouseover', () => {
button.style.transform = 'scale(1.1) rotate(10deg)';
button.style.boxShadow = '0 8px 25px rgba(218, 27, 96, 0.6)';
});
button.addEventListener('mouseout', () => {
button.style.transform = 'scale(1) rotate(0)';
button.style.boxShadow = '0 6px 20px rgba(0, 0, 0, 0.4)';
});
let panel = null;
button.addEventListener('click', () => {
if (!panel || panel.style.display === 'none') {
if (!panel) {
panel = createControlPanel();
panel.style.display = 'block';
} else {
panel.style.display = 'block';
panel.style.transform = 'translateY(0)';
panel.style.opacity = '1';
}
} else {
panel.style.transform = 'translateY(20px)';
panel.style.opacity = '0';
setTimeout(() => panel.style.display = 'none', 300);
}
});
document.body.appendChild(button);
}
// 添加全局样式
GM_addStyle(`
#blocker-panel input:focus {
outline: none;
border-color: #ff8a00;
box-shadow: 0 0 0 3px rgba(255, 138, 0, 0.25);
}
#blocker-rules-list::-webkit-scrollbar {
width: 8px;
}
#blocker-rules-list::-webkit-scrollbar-track {
background: rgba(0, 0, 0, 0.15);
border-radius: 4px;
}
#blocker-rules-list::-webkit-scrollbar-thumb {
background: rgba(255, 138, 0, 0.6);
border-radius: 4px;
}
#blocker-rules-list::-webkit-scrollbar-thumb:hover {
background: rgba(255, 138, 0, 0.8);
}
input[type="checkbox"]:checked + span > span {
transform: translateX(20px);
}
`);
// 注册菜单命令
GM_registerMenuCommand('打开屏蔽工具', function() {
const btn = document.getElementById('blocker-control-btn');
if (btn) btn.click();
});
// 初始化
function init() {
// 添加控制按钮
addControlButton();
// 首次屏蔽
blockResults();
// 监听DOM变化处理动态内容
const observer = new MutationObserver(blockResults);
observer.observe(document.body, { childList: true, subtree: true });
// 显示欢迎通知
setTimeout(() => {
const rulesCount = loadRules().length;
showNotification(`搜索结果屏蔽工具已启用!已加载 ${rulesCount} 条规则`, 'success');
}, 1500);
}
// 页面加载完成后初始化
if (document.readyState === 'loading') {
window.addEventListener('DOMContentLoaded', init);
} else {
setTimeout(init, 1000);
}
})();