您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Esconde "job cards" de la búsqueda basado en palabras clave.
// ==UserScript== // @name Bumeran Job Filter // @namespace Bumeran-Job-Filter // @version 1.8 // @description Esconde "job cards" de la búsqueda basado en palabras clave. // @author masterofobzene // @homepage https://github.com/masterofobzene/UserScriptRepo // @match https://www.bumeran.com.ar/* // @license GNU GPLv3 // @grant GM_setValue // @grant GM_getValue // @grant GM_registerMenuCommand // ==/UserScript== (function() { 'use strict'; const KEYWORDS_KEY = 'bumeran_exclude_keywords'; let liveDebounce, domDebounce; // — storage helpers — async function getKeywords() { const stored = await GM_getValue(KEYWORDS_KEY, ''); return stored .split(',') .map(k => k.trim().toLowerCase()) .filter(Boolean); } async function saveKeywords(keywords) { await GM_setValue(KEYWORDS_KEY, keywords.join(',')); console.log('[BumeranFilter] Saved keywords:', keywords); } // — filtering — function resetJobsDisplay() { document.querySelectorAll('a').forEach(a => { if (a.querySelector('h2')) a.style.display = ''; }); } function filterJobs(keywords) { resetJobsDisplay(); if (!keywords.length) return; document.querySelectorAll('a') .forEach(link => { const h2 = link.querySelector('h2'); if (!h2) return; const txt = h2.textContent.trim().toLowerCase(); if (keywords.some(kw => txt.includes(kw))) { link.style.display = 'none'; console.log(`[BumeranFilter] Hiding: "${txt}"`); } }); } // — UI panel — function addUI() { const c = document.createElement('div'); Object.assign(c.style, { position: 'fixed', bottom: '10px', left: '10px', // Move to lower left zIndex: 9999, background: '#fff', border: '1px solid #ccc', padding: '10px', boxShadow: '0 2px 5px rgba(0,0,0,0.2)' }); c.innerHTML = ` <label><strong>Excluir keywords:</strong></label><br> <input id="keywordInput" type="text" style="width:200px" placeholder="e.g. java, senior, python" /> <small style="display:block;margin-top:4px;color:#666"> Los filtros se aplican dinámicamente </small> `; document.body.appendChild(c); const input = c.querySelector('#keywordInput'); input.addEventListener('input', () => { clearTimeout(liveDebounce); liveDebounce = setTimeout(async () => { const kws = input.value .split(',') .map(s => s.trim().toLowerCase()) .filter(Boolean); await saveKeywords(kws); filterJobs(kws); }, 200); }); } // — run once jobs have appeared — function jobsReady(cb) { if (document.querySelector('a h2')) { cb(); return; } const obs = new MutationObserver((m,o) => { if (document.querySelector('a h2')) { o.disconnect(); cb(); } }); obs.observe(document.body, { childList: true, subtree: true }); } // — catch URL changes if history API fails — function watchUrlChanges(onChange) { let last = location.href; setInterval(() => { if (location.href !== last) { last = location.href; onChange(); } }, 500); } // — main init — (async function init() { console.log('[BumeranFilter] v1.8 starting…'); addUI(); // load + auto-apply saved filters const saved = await getKeywords(); const inp = document.getElementById('keywordInput'); if (saved.length) inp.value = saved.join(', '); jobsReady(() => filterJobs(saved)); // re-apply whenever the URL changes watchUrlChanges(async () => { const kws = await getKeywords(); jobsReady(() => filterJobs(kws)); }); // also watch DOM mutations (e.g. new jobs loaded dynamically) const mo = new MutationObserver(() => { clearTimeout(domDebounce); domDebounce = setTimeout(async () => { const kws = await getKeywords(); filterJobs(kws); }, 300); }); mo.observe(document.body, { childList: true, subtree: true }); // menu command to clear GM_registerMenuCommand('Borrar todas las Exclude Keywords', async () => { await GM_setValue(KEYWORDS_KEY, ''); location.reload(); }); })(); })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址