Blocks keywords and websites from Google search.
当前为
// ==UserScript==
// @name Google Exclusions Dynamic Clean
// @namespace http://tampermonkey.net/
// @version 1.8
// @description Blocks keywords and websites from Google search.
// @author ScriptKing
// @match https://www.google.com/search*
// @match https://www.google.com/
// @grant none
// @license MIT
// ==/UserScript==
(function() {
'use strict';
// =========================
// CONFIG: Your exclusion list
// =========================
// IMPORTANT
// (1) update your website search engine to exclude the same keywords below
// like this: https://www.google.com/search?q=%s+-site:reddit.com+-antix
// (2) put the exclusions also below
const exclusions = ['reddit.com', 'antix']; //
// =========================
// HELPER FUNCTIONS
// =========================
// Wait for element with polling
function waitForElement(selector, timeout = 5000, interval = 100) {
return new Promise((resolve, reject) => {
const start = Date.now();
const check = () => {
const el = document.querySelector(selector);
if (el) {
resolve(el);
} else if (Date.now() - start > timeout) {
reject(new Error('Element not found'));
} else {
setTimeout(check, interval);
}
};
check();
});
}
// Check if exclusion looks like a domain (contains a dot)
function isDomain(str) {
return str.includes('.');
}
// Append exclusions if not already present
function appendExclusions(query) {
let newQuery = query;
exclusions.forEach(ex => {
let exStr;
if (isDomain(ex)) {
exStr = `-site:${ex}`;
} else {
exStr = `-${ex}`;
}
if (!newQuery.toLowerCase().includes(exStr.toLowerCase())) {
newQuery += ` ${exStr}`;
}
});
return newQuery;
}
// Clean query box by removing exclusion terms
function cleanQueryBox() {
const selectors = 'input[name="q"], textarea[name="q"], input[type="search"], textarea';
const queryBox = document.querySelector(selectors);
if (queryBox && queryBox.value) {
let cleaned = queryBox.value;
exclusions.forEach(ex => {
const exEsc = ex.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
if (isDomain(ex)) {
// Remove patterns like " -site:ex.com" or "-site:ex.com " with optional spaces
const regex = new RegExp(`\\s*-site:${exEsc}\\s*`, 'gi');
cleaned = cleaned.replace(regex, ' ');
} else {
// Remove patterns like " -keyword" or "-keyword " with optional spaces
const regex = new RegExp(`\\s*-${exEsc}\\s*`, 'gi');
cleaned = cleaned.replace(regex, ' ');
}
});
// Normalize spaces
cleaned = cleaned.replace(/\s+/g, ' ').trim();
if (cleaned !== queryBox.value) {
queryBox.value = cleaned;
// Trigger input event for UI updates
['input', 'change'].forEach(eventType => {
queryBox.dispatchEvent(new Event(eventType, { bubbles: true }));
});
}
}
}
// =========================
// SEARCH BUTTON HANDLER
// =========================
async function setupSearchHandler() {
try {
// Wait for search button
const button = await waitForElement('button[aria-label="Search"], input[name="btnK"], button[name="btnK"]');
const queryBox = document.querySelector('input[name="q"], textarea[name="q"]') || button.closest('form')?.querySelector('input[name="q"], textarea');
button.addEventListener('click', (e) => {
if (queryBox && queryBox.value.trim()) {
e.preventDefault();
queryBox.value = appendExclusions(queryBox.value);
// Re-trigger submit after modification
setTimeout(() => {
if (queryBox.form) {
queryBox.form.submit();
}
}, 0);
}
}, { capture: true });
} catch (err) {
console.error('Search button not found:', err);
}
}
// =========================
// INITIALIZATION
// =========================
function initialize() {
cleanQueryBox();
setupSearchHandler();
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initialize);
} else {
initialize();
}
// Observe DOM changes for dynamic cleaning
const observer = new MutationObserver(() => {
cleanQueryBox();
});
// Start observing once body is available
if (document.body) {
observer.observe(document.body, { childList: true, subtree: true });
}
// Listen for Enter key
document.addEventListener('keydown', (e) => {
if (e.key === 'Enter' && e.target.matches('input[name="q"], textarea[name="q"]')) {
const queryBox = e.target;
if (queryBox.value.trim()) {
queryBox.value = appendExclusions(queryBox.value);
}
}
});
})();