// ==UserScript== // @name BOSS 直聘助手魔改中 // @namespace http://tampermonkey.net/ // @version 1.0 // @description (1)搜索页面增加按钮:只显示当前 HR 在线的职位。(2)职位详情页面增加浮窗显示:HR 是否最近活跃;是否接受应届生。以下是新增功能 还在完善中 1 改进了去世相关的 2 可以隐藏职业跟行业 我用了其他人搞的好多都会封号我就魔改了下不会封号版本的 自用中 // @author Rostal // @license MIT // @icon https://www.zhipin.com/favicon.ico // @match https://www.zhipin.com/job_detail/* // @match *://*/* // @grant none // @downloadURL none // ==/UserScript== (function () { 'use strict'; let document1, document2; let listPageDocument = null; // 创建置于最顶层的悬浮弹窗 function createFloatingPopup(text, textColor) { var iframe = document.createElement('iframe'); iframe.style.position = 'fixed'; iframe.style.top = '10px'; iframe.style.left = '50%'; iframe.style.transform = 'translateX(-50%)'; iframe.style.width = '80%'; iframe.style.height = 'auto'; iframe.style.backgroundColor = 'transparent'; // 透明背景 iframe.style.border = 'none'; iframe.style.zIndex = '2147483647'; // 保证弹窗在最上层 iframe.style.boxShadow = '0 5px 15px rgba(0,0,0,0.5)'; iframe.style.borderRadius = '10px'; //iframe.sandbox = 'allow-same-origin'; // 添加 sandbox 属性 // 将 iframe 添加到页面中 //document.body.appendChild(iframe); /* var style = ` #floatingPopup { position: fixed; top: 10px; left: 50%; transform: translateX(-50%); width: 80%; background: rgba(0, 0, 0, 0.9); color: white; padding: 20px; box-sizing: border-box; text-align: center; border-radius: 10px; box-shadow: 0 5px 15px rgba(0,0,0,0.5); z-index: 2147483647; transition: opacity 0.3s ease-in-out; filter: grayscale(0%) !important; } #floatingPopup div { filter: none; /* 取消文本的灰色滤镜 */ // color: ${textColor}!important; /* 文本颜色 */ /* } #closePopup { position: absolute; top: 5px; right: 10px; cursor: pointer; font-size: 1.5em; font-weight: bold; } #closePopup:hover { color: #ddd; } `;*/ const randomParam = Math.random(); let iframeSrcdoc = ` X
${text}
`; iframe.srcdoc = `${iframeSrcdoc}?${randomParam}`; //iframe.srcdoc = iframeSrcdoc; document.body.appendChild(iframe); iframe.onload = function() { const iframeDocument = iframe.contentDocument || iframe.contentWindow.document; if (iframeDocument) { const style = document.createElement('style'); style.textContent = ` html, body { background-color: rgba(0, 0, 0, 0.9); font-family: Arial, sans-serif; } body { color: ${textColor}; fill: ${textColor}; } #closePopup { position: absolute; top: 5px; right: 10px; cursor: pointer; font-size: 1.5em; font-weight: bold; background: rgba(0, 0, 0, 0.6); border-radius: 50%; width: 30px; height: 30px; text-align: center; color: white; display: flex; justify-content: center; align-items: center; transition: background 0.3s; } #closePopup:hover { background: rgba(0, 0, 0, 0.8); } #popupContent { margin-top: 30px; font-size: 2em; font-weight: bold; padding: 10px; color: ${textColor}; fill: ${textColor}; } `; iframeDocument.head.appendChild(style); } }; /* iframe.onload = function() { const setIframeStyles = () => { try { const iframeDocument = iframe.contentDocument || iframe.contentWindow.document; if(iframeDocument && iframeDocument.body){ const body = iframeDocument.body; body.style.color = `${textColor} !important`; const popupContent = iframeDocument.getElementById('popupContent'); if(popupContent){ popupContent.style.color = `${textColor} !important`; } } else { requestAnimationFrame(setIframeStyles); } } catch (e) { console.error('Failed to apply styles to iframe:', e); } }; requestAnimationFrame(setIframeStyles); };*/ // iframe 内的内容,使用 srcdoc 来定义 HTML 内容 //iframe.srcdoc = iframeSrcdoc; // 给 iframe 添加 ID 方便关闭时引用 iframe.id = 'iframePopup'; // 将 iframe 添加到页面中 //document.body.appendChild(iframe); /* iframe.onload = function() { // 创建独立的样式表 const style = document.createElement('style'); style.textContent = ` body { font-family: Arial, sans-serif; margin: 0; padding: 0; background-color: rgba(0, 0, 0, 0.9); color: ${textColor} !important; /* 明确设置文字颜色为红色 */ /* text-align: center; overflow: hidden; } #closePopup { position: absolute; top: 5px; right: 10px; cursor: pointer; font-size: 1.5em; font-weight: bold; background: rgba(0, 0, 0, 0.6); border-radius: 50%; width: 30px; height: 30px; text-align: center; color: white; display: flex; justify-content: center; align-items: center; transition: background 0.3s; } #closePopup:hover { background: rgba(0, 0, 0, 0.8); } #popupContent { margin-top: 30px; font-size: 2.0em; padding: 10px; } `; // 使用 DOMParser 解析 srcdoc /* const parser = new DOMParser(); const doc = parser.parseFromString(iframeSrcdoc, 'text/html'); const head = doc.querySelector('head'); head.appendChild(style); iframe.srcdoc = doc.documentElement.outerHTML */ }; /*iframe.srcdoc = `
X
${text}
`;*/ // 给 iframe 添加 ID 方便关闭时引用 /*iframe.id = 'iframePopup'; // 将 iframe 添加到页面中 document.body.appendChild(iframe); // 在父页面中取消滤镜影响 setTimeout(() => { // 使用 setTimeout 确保 iframe 已经插入 DOM const popups = document.querySelectorAll('iframe'); popups.forEach(popup => { popup.style.filter = 'invert(100%)'; // 使用 invert 反转滤镜 }); }, 0) /* // 添加样式 var styleElement = document.createElement('style'); styleElement.type = 'text/css'; styleElement.innerHTML = style; document.head.appendChild(styleElement); */ // 将弹窗添加到页面中 //document.body.insertAdjacentHTML('afterbegin', popupHTML); /* // 关闭弹窗的事件处理 document.getElementById('closePopup').addEventListener('click', function () { var popup = document.getElementById('floatingPopup'); popup.style.opacity = '0'; setTimeout(function () { popup.style.display = 'none'; }, 300); });*/ function createGrayOverlay() { // 创建一个全屏的灰色遮罩层 let overlay = document.createElement('div'); overlay.id = 'grayOverlay'; overlay.style.position = 'fixed'; overlay.style.top = '0'; overlay.style.left = '0'; overlay.style.width = '100vw'; overlay.style.height = '100vh'; overlay.style.backgroundColor = 'rgba(0, 0, 0, 0.8)'; overlay.style.zIndex = '9999'; overlay.style.display = 'none'; document.body.appendChild(overlay); return overlay; } function showGrayOverlay() { let overlay = document.getElementById('grayOverlay'); if (!overlay) { overlay = createGrayOverlay(); } overlay.style.display = 'block'; } function enableGrayMode() { // 获取 body 或 html 元素 let body = document.body; let overlay = document.createElement('div'); // 设置全局样式,应用灰色滤镜,并禁用页面交互(如果需要) body.style.filter = 'grayscale(100%)'; body.style.pointerEvents = 'none'; // 禁用交互,如果需要 /* let popups = document.querySelectorAll('iframe'); popups.forEach(popup => { popup.style.filter = 'none'; // 取消弹窗的灰色滤镜 popup.style.pointerEvents = 'auto'; // 重新启用弹窗的交互 });*/ } function runJobDetail() { console.log('jrxq'); // ======== HR 是否最近活跃 ======== let hrDeadTexts = ["在线", "刚刚活跃", "今日活跃"]; let bossActiveTime = document1.querySelector('div.job-boss-info span.boss-active-time'); let bossname = document1.querySelector('div.job-boss-info h2.name'); let gtButton = document1.querySelector('a.btn.btn-startchat'); let salaryText = document1.querySelector('span.salary'); let bossInfoAttr = document1.querySelector('div.boss-info-attr'); let salary = salaryText ? salaryText.textContent.trim() : ''; let bossInfo = bossInfoAttr ? bossInfoAttr.textContent.trim().split('·')[0] : ''; let nameText = bossname ? bossname.textContent.trim().split(' ')[0].split('\n')[0] : null; if (bossActiveTime) { let bossActiveTimeText = bossActiveTime.textContent; if (!hrDeadTexts.includes(bossActiveTimeText)) { enableGrayMode(); createFloatingPopup("SB"+nameText+"已去世| 请允许我们在此献上最后的告别,以纪念其在Boss直聘中留下的足迹与回忆🕯🕯🕯", "red"); return; } } // 如果按钮是“继续沟通”,就存储职位信息 if (gtButton && gtButton.textContent.trim() === "继续沟通") { console.log('检测到继续沟通1,执行存储职位信息'); window.localStorage.setItem('jobDetailInfo', JSON.stringify({ salary, bossInfo, nameText })); // 将信息存储到localStorage window.localStorage.setItem('jobDetailProcessed', 'true'); // 标记数据已处理 console.log('localStorage',localStorage) runGeekJob() //window.location.href = '/geek/job'; // 跳转到列表页面 } else if (gtButton) { // 按钮是"立即沟通",我们需要监听它的变化 console.log('按钮是“立即沟通”'); console.log('window.localStorage',window.localStorage) const observer = new MutationObserver(() => { if (gtButton.textContent.trim() === "继续沟通") { console.log('检测到继续沟通2,执行存储职位信息'); window.localStorage.setItem('jobDetailInfo', JSON.stringify({ salary, bossInfo, nameText })); // 将信息存储到localStorage window.localStorage.setItem('jobDetailProcessed', 'true'); // 标记数据已处理 //window.location.href = '/geek/job'; // 跳转到列表页面 runGeekJob() } }); // 监听按钮文本的变化 observer.observe(gtButton, { childList: true, subtree: true, }); } // ======== 是否接受应届生 ======== let jobName = document1.querySelector('div.info-primary > div.name'); if (jobName) { let jobNameText = jobName.textContent; let regex = /应届.*生?/; if (regex.test(jobNameText)) { createFloatingPopup("接受应届生", "green"); return; } } let jobDetail = document1.querySelector('div.job-detail div.job-sec-text'); if (jobDetail) { let jobDetailText = jobDetail.textContent; let regex = /接受.*应届.*生/; let regex2 = /应届.*生.*可/; let regex3 = /欢迎.*应届.*生/; let regex4 = /应届.*生.*优先/; if (regex.test(jobDetailText) || regex2.test(jobDetailText) || regex3.test(jobDetailText) || regex4.test(jobDetailText)) { createFloatingPopup("接受应届生", "green"); return; } } } function onlineFilter() { console.log('1. bfEle 不存在,执行添加'); const bfEle = document.querySelector('.__boss_filter.condition-filter-select'); if (bfEle) { console.log('1. bfEle 已经存在'); // 先移除选中样式 bfEle.classList.remove('is-select'); } else { // 不存在则创建并添加到DOM树中 try { runGeekJob(); } catch (error) { console.log('新增筛选出错', error); } } } function runGeekJob() { console.log('dyrunGeekJob') // 保存原始的 XMLHttpRequest const originalXHR = XMLHttpRequest; // 重写 XMLHttpRequest 构造函数 XMLHttpRequest = function() { const xhr = new originalXHR(); // 重写 open 方法 const originalOpen = xhr.open; xhr.open = function(method, url) { //console.log('捕获到请求 URL:', url); // 输出请求的 URL if (url.includes('joblist.json')) { //console.log('捕获到 joblist.json 请求:', url); } return originalOpen.apply(this, arguments); // 调用原始的 open 方法 }; // 重写 send 方法 const originalSend = xhr.send; xhr.send = function(data) { // 在请求完成时处理响应 xhr.onload = function() { if (xhr.status === 200) { try { // 确保响应类型是 JSON 格式 const data = JSON.parse(xhr.responseText); //console.log('解析后的数据:', data); if (data.zpData && data.zpData.jobList) { const jobList = data.zpData.jobList; jobList.forEach((job, index) => { //console.log('job',job) //console.log('职位名称:', job.jobName); //console.log('公司名称:', job.brandName); //console.log('bossName',job.bossName) //console.log('ProxyJob:', job.proxyJob); // 若该字段存在 //console.log('ProxyType:', job.proxyType); // 若该字段 window.localStorage.setItem('jobListData', JSON.stringify(data.zpData.jobList)); }); } } catch (e) { console.error('解析 joblist.json 响应出错:', e); } } else { console.error('请求失败,状态码:', xhr.status); } }; return originalSend.apply(this, arguments); // 调用原始的 send 方法 } return xhr; }; // 从localStorage获取职位信息 /* const jobDetailProcessed = window.localStorage.getItem('jobDetailProcessed'); if (jobDetailProcessed === 'true') { console.log('jobDetailProcessed') //try { let jobDetailInfo = JSON.parse(window.localStorage.getItem('jobDetailInfo')); console.log('jobDetailInfo',jobDetailInfo) if (jobDetailInfo) { // 提取相关的职位信息 let { salary, bossInfo, nameText } = jobDetailInfo; console.log('czlistItems'); console.log('document',document); console.log('document.querySelectorAll',document.querySelectorAll); console.log('window.onload',document.referrer) //window.onload = function() { const savedLIState = JSON.parse(localStorage.getItem('liState')); console.log('savedLIState',savedLIState) console.log('savedLIState.length',savedLIState.length) if (savedLIState && savedLIState.length > 0) { console.log('jrpd',window.opener.document) savedLIState.forEach(savedState => { const li = window.opener.document.querySelectorAll('li')[savedState.index]; if (li) { li.style.display = 'none'; // 修改原页面的
  • 元素 } }); let listItems = document.querySelectorAll('ul.job-list-box > li'); //console.log('listItems',listItems); listItems.forEach(function (item) { let itemSalary = item.querySelector('span.salary') ? item.querySelector('span.salary').textContent.trim() : ''; let itemBossInfo = item.querySelector('div.boss-info-attr') ? item.querySelector('div.boss-info-attr').textContent.trim() : ''; let itemName = item.querySelector('h2.name') ? item.querySelector('h2.name').textContent.trim().split(' ')[0] : ''; // 比对 salary、bossInfo 和 name,如果都相同,则隐藏该职位项 if (itemSalary === salary && itemBossInfo === bossInfo && itemName === nameText) { console.log('找到匹配项,隐藏该职位'); item.style.display = 'none'; // 强制浏览器重新渲染,确保隐藏生效 //item.offsetHeight; // 调用强制重排的方法 } }); //} } } } */ /*}catch (error) { // 捕获错误时,打印错误并跳过 console.error('Error parsing jobDetailInfo from localStorage:', error); }*/ console.log('2. bfEle 不存在,执行添加'); // 创建按钮元素 let button = document.createElement('div'); button.innerHTML = `
    浪费时间GUN
    `; button.classList.add('condition-filter-select', '__boss_filter'); //let button = document.createElement('button'); //button.innerHTML = '隐藏浪费时间货色'; // 设置按钮显示的文本 //button.style.position = 'fixed'; // 设置按钮位置为固定 //button.style.left = '0'; // 将按钮放置在页面的最左侧 //button.style.top = '50%'; // 将按钮垂直居中 //button.style.transform = 'translateY(-50%)'; // 垂直居中的偏移量 //button.style.zIndex = '2147483647'; // 设置按钮的z-index为最大值,确保其在最高层级 //button.style.padding = '10px'; // 设置按钮的内边距 //button.style.cursor = 'pointer'; // 设置鼠标悬停时的光标样式 // button.style.fontSize = '12px'; // 设置按钮字体大小 // 添加点击事件监听器 button.addEventListener('click', function () { // 获取所有的
  • 元素 let listItems = document.querySelectorAll('ul.job-list-box > li'); const jobListData = JSON.parse(window.localStorage.getItem('jobListData')) || []; const keywords = ['主播', '直播', '不露脸','打字聊天','老师','讲师','教师']; const brandIndustrykey = ['即时配送','培训/辅导机构'] // 遍历每个
  • 元素 listItems.forEach(function (item, index) { let bossOnlineTag = item.querySelector('span.boss-online-tag'); console.log('bossOnlineTag',bossOnlineTag); let dz = item.querySelector('img.job-tag-icon'); console.log('dz',dz); let jobname = item.querySelector('span.job-name').firstChild.textContent.trim(); console.log('jobname',jobname); const bossname = item.querySelector('div.info-public').firstChild.textContent.trim(); console.log('bossname',bossname); console.log('jobListDataxbossname',jobListData[index].bossName); const job = jobListData[index]; console.log('job',job) const brandIndustry = job.brandIndustry console.log('brandIndustry',brandIndustry) // 获取当前元素的样式 let style = window.getComputedStyle(item); const jobname1 = "需要一位程序员"; const brandIndustry1 = "软件开发,互联网"; // 如果没有找到 boss-online-tag 并且元素是可见的,则隐藏该
  • 元素 // 如果元素是隐藏的,则显示它 console.log('keyword',keywords.some(keyword => jobname1.includes(keyword))); console.log('bossOnlineTag',!bossOnlineTag); console.log('dz',dz); console.log('job.proxyJob',job.proxyJob === 1); console.log('brandIndustryItem',brandIndustrykey.some(brandIndustryItem => brandIndustry1.includes(brandIndustryItem))); if ((brandIndustrykey.some(brandIndustryItem => brandIndustry.includes(brandIndustryItem)) || keywords.some(keyword => jobname.includes(keyword)) || !bossOnlineTag || dz || job.proxyJob === 1) && style.display !== 'none') { item.style.display = 'none'; } else if (style.display === 'none') { item.style.display = ''; // 使用空字符串将元素的display属性恢复到默认值 } }); }); // 将按钮添加到页面中 document.body.appendChild(button); // 插入到父元素 .search-condition-wrapper 最后一个元素之前 const observer = new MutationObserver(function(mutationsList, observer) { let parentNode = document.querySelector('.search-condition-wrapper'); console.log('parentNode',parentNode) if (parentNode !== null) { let lastChild = parentNode.lastChild; parentNode.insertBefore(button, lastChild); observer.disconnect(); } else { console.log('3. parentNode 不存在,无法插入filter'); } }); observer.observe(document.body, { childList: true, subtree: true }); } // 确保页面完全加载后再执行逻辑 //window.onload = function () { let currentUrl = window.location.href; console.log('currentUrl',currentUrl) if (currentUrl.includes("/job_detail/")) { document1 = document; //console.log('document1',document1) runJobDetail(); } else if (currentUrl.includes("/geek/job")) { console.log('jrzys') const observer = new MutationObserver(() => { document2 = document // 确保 DOM 加载完毕再执行 runGeekJob //console.log('12. bfEle 不存在,执行添加'); //console.log('document',document.querySelector); //if (document.querySelector('ul.job-list-box')) { //console.log('23. bfEle 不存在,执行添加'); //window.addEventListener('storage', function (event) { //if (event.key === 'jobDetailProcessed' && event.newValue === 'true') { console.log('jrzy'); const liElements = document.querySelectorAll('li'); const liState = []; liElements.forEach((li, index) => { liState.push({ index: index, id: li.id, style: li.style.display // 保存 display 样式 }); }); // 使用 localStorage 保存状态 localStorage.setItem('liState', JSON.stringify(liState)); //console.log('document2',document2) runGeekJob(); observer.disconnect(); // 断开观察,避免重复触发 //}; //}); //}; }); // 配置 MutationObserver 来观察 DOM 变化 observer.observe(document.body, { childList: true, subtree: true }); //runGeekJob(); } //} })();