您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
根据需要添加关键字,然后可以把页面上相对应公司的招聘条目给忽略
// ==UserScript== // @name IgnoreSomeCompanies // @namespace https://github.com/hfc1994 // @version 1.1.1 // @description 根据需要添加关键字,然后可以把页面上相对应公司的招聘条目给忽略 // @author 枯木 // @license GPL // @icon https://avatars2.githubusercontent.com/u/32028349?s=40&v=4 // @match https://search.51job.com/list/* // @match https://sou.zhaopin.com/* // @grant none // ==/UserScript== /** * 根据添加的指定关键字,忽略求职网站上指定公司的招聘条目 * 如果发现bug,非常欢迎向我提出来https://github.com/hfc1994/IgnoreSomeCompanies */ let companies = [] let website = '' // 初始化,用来读取localStorage // 存储格式key:companies,value:['',''] function init() { judgeWebsite() appendGlobalStyle() appendFloatDiv() try { companies = JSON.parse(window.localStorage.getItem('companies')) if (companies === null || companies === undefined || companies.length === 0) { companies = [] console.warn('页面暂无需要过滤的数据') return } else { for (let i=0; i<companies.length; i++) { document.getElementById('ISC_content').appendChild(buildContentChildNode(companies[i], i)) } doIgnore() } } catch(err) { console.error(err) } } function judgeWebsite() { let href = window.location.href if (href.indexOf('sou.zhaopin.com') !== -1) { website = 'zlzp' addMutationObserver() } else { website = '51job' } console.log(website) } function addMutationObserver() { // 因为zlzp使用的都是ajax加载的数据,所以只能通过监视DOM变动 let observer = new MutationObserver(() => { // console.log('DOM changed') doIgnore() }) let number = setInterval(() => { let target = document.getElementById('listContent') if (null !== target) { doIgnore() // DOM布局第一次形成,先过滤一遍 observer.observe(target, {'childList': true}) clearInterval(number) // console.log('observer设置完毕,定时任务结束') } else { // console.log('dom还没有初始化完成,500毫秒后重试') } }, 500) } function doIgnore() { let compDivs = getDivListToIgnore() for (let i=0; i<compDivs.length; i++) { let item = compDivs[i] if (alreadyBeIgnored(item)) { continue } let cName = getRealCompanyName(item) if (isIgnoreCompany(cName)) { // console.log('匹配到:' + cName) addIgnoreClassTag(item) appendNewChildNode(item, cName) } } } function getDivListToIgnore() { if (website === '51job') { return document.querySelectorAll('.dw_table .el') } else { return document.querySelectorAll('.contentpile__content__wrapper .clearfix') } } function getRealCompanyName(node) { if (website === '51job') { return node.getElementsByClassName('t2')[0].textContent.trim() } else { return node.getElementsByClassName('company_title')[0].textContent.trim() } } // 添加一些全局样式 function appendGlobalStyle() { // 需要被忽略的节点 buildStyle('.ISC_ignoreNode{height:30px !important;background-color:#dbecfe !important;}') // 需要被忽略的子节点 buildStyle('.ISC_ignoreChildNode{display:none !important;}') // toolbox节点里面的 if (website === '51job') { // 新添加的节点 buildStyle('.ISC_appendNode{font-size: 10px;text-align: center;margin-top: -5px;color: #bababa;}') buildStyle('#ISC_info {position: fixed;bottom: 126px;margin-left: 1042px;text-align: center;padding-top: 5px;height: 48px;width: 48px;}') buildStyle('#ISC_input {bottom: 182px;height: 30px;}') buildStyle('#ISC_content {bottom: 215px;min-height: 150px;}') buildStyle('#ISC_content,#ISC_input {position: fixed;margin-left: 890px;box-shadow: 1px 1px 3px 0px #a3a3a3;width: 200px;opacity: 0.75;z-index: 10;}') } else { // 新添加的节点 buildStyle('.ISC_appendNode{font-size: 10px;text-align: center;padding-top: 5px;color: #bababa;}') buildStyle('#ISC_info {position: fixed;bottom: 22px;margin-left: 800px;text-align: center;padding-top: 5px;height: 48px;width: 48px;}') buildStyle('#ISC_input {bottom: 73px;height: 30px;}') buildStyle('#ISC_content {bottom: 106px;min-height: 150px;}') buildStyle('#ISC_content,#ISC_input {position: fixed;margin-left: 800px;box-shadow: 1px 1px 3px 0px #a3a3a3;width: 200px;opacity: 0.75;z-index: 10;}') // 额外调整UI的 buildStyle('#filterInput {line-height: initial;background: #fff;width: 155px;height: 21px;border: 1px solid #aaa;}') buildStyle('#filterButton {border: 1px solid #aaa;background-color: #eee;width: 31px;height: 22px;font-size: 14px;margin-bottom: 6px;}') } buildStyle('#ISC_info:hover {border-radius: 10px;box-shadow: 2px 2px 5px 0px #a3a3a3;}') buildStyle('#ISC_info:active {transform: scale(0.8);-webkit-transform: scale(0.8);-moz-transform: scale(0.8);-ms-transform: scale(0.8);}') buildStyle('#ISC_content,#ISC_input,#ISC_info,.ISC_keyword {background-color: #ecf5ff;border: 1px solid #409eff;color: #409eff;}') buildStyle('.ISC_keyword {margin: 5px;padding: 1px 2px;display: inline-block;color: #000;cursor: pointer;box-shadow: 2px 2px 4px 0px #a3a3a3;}') buildStyle('.ISC_keyword:hover {transform: scale(1.1);-webkit-transform: scale(1.1);-moz-transform: scale(1.1);-ms-transform: scale(1.1);}') buildStyle('#ISC_info,.ISC_keyword {transition: all 0.3s;-webkit-transition: all 0.3s;-moz-transition: all 0.3s;-ms-transition: all 0.3s;}') buildStyle('#filterInput, #filterButton {margin: 3px 2px;}') buildStyle('#ISC_node_copy {opacity: 0.4;}') } // 根据给定内容构造样式 function buildStyle(content) { let newStyle = document.createElement('style') newStyle.type = 'text/css' newStyle.innerHTML = content document.head.appendChild(newStyle) } // 是否是需要被忽略的 function isIgnoreCompany(cName) { for (let i = 0; i < companies.length; i++) { let ignoreName = companies[i] if (cName === ignoreName || cName.indexOf(ignoreName) !== -1) { return true } } return false } // 是否已经被过滤过了,true为已经被过滤了 function alreadyBeIgnored(node) { for (let i=0; i<node.classList.length; i++) { if ('ISC_ignoreNode' === node.classList[i]) { return true } } return false } // 处理需要被忽略的目标节点 function addIgnoreClassTag(node) { node.classList.add('ISC_ignoreNode') for (let j=0; j<node.children.length; j++) { node.children[j].classList.add('ISC_ignoreChildNode') } } // 被忽略的节点上增加一个div,用于显示忽略信息 function appendNewChildNode(node, name) { let div = document.createElement('div') div.classList.add('ISC_appendNode') div.innerText = '被忽略的公司 -> ' + name // 把被忽略的节点给恢复 div.onclick = function (event) { event.target.parentNode.classList.remove('ISC_ignoreNode') let children = event.target.parentNode.children // HTMLCollection没有forEach // appendNode是append上去的,是在最后一个 for (let i=0; i<children.length; i++) { if (children[i].classList.contains('ISC_ignoreChildNode')) { children[i].classList.remove('ISC_ignoreChildNode') } else if (children[i].classList.contains('ISC_appendNode')) { children[i].remove() } } document.getElementById('ISC_node_copy').remove() } div.onmouseenter = function (event) { let fNode = event.target.parentNode let fNodeCopy = fNode.cloneNode(true) fNodeCopy.classList.remove('ISC_ignoreNode') fNodeCopy.id = 'ISC_node_copy' fNodeCopy.getElementsByClassName('ISC_appendNode')[0].remove() for (let i=0; i<fNodeCopy.children.length; i++) { fNodeCopy.children[i].classList.remove('ISC_ignoreChildNode') } let nextNode = fNode.nextSibling if (nextNode === null) { fNode.parentNode.appendChild(fNodeCopy) } else { fNode.parentNode.insertBefore(fNodeCopy, nextNode) } } div.onmouseleave = function () { document.getElementById('ISC_node_copy').remove() } node.appendChild(div) } // 添加toolbox function appendFloatDiv() { let toolbox = document.createElement('div') toolbox.id = 'ISC_toolbox' let content = document.createElement('div') content.id = 'ISC_content' content.style = 'display: none;' let input = document.createElement('div') input.id = 'ISC_input' input.style = 'display: none;' input.innerHTML = '<input id="filterInput" placeholder="关键字" type="text"/><button id="filterButton" type="button">添加</button>' let info = document.createElement('div') info.id = 'ISC_info' info.innerHTML = '<span>添加<br/>忽略</span>' info.onclick = function() { // 切换显示与否 let visible = divVisibleSwitch() if (visible === 'block') { document.onwheel = function() { divVisibleSwitch() document.onwheel = undefined } } else { document.onwheel = undefined } } toolbox.appendChild(content) toolbox.appendChild(input) toolbox.appendChild(info) if (website === '51job') { document.getElementById('resultList').appendChild(toolbox) } else { document.getElementById('listItemPile').appendChild(toolbox) } document.getElementById('filterButton').onclick = function () { let keyword = document.getElementById('filterInput').value.trim() if (keyword.length === 0) { alert('不能使用空字符串') return } if (companies.length === 128) { alert('关键字限定数量为128,此刻关键字数量已达上限,可点击关键字进行删减') document.getElementById('filterInput').value = '' return } let status = addIntoCompanies(keyword) if (status !== -1) { let index = modifyLocalStorage() if (status !== 0) { // 等于0时已经在检测时替换掉了 // 在content中显示该关键字 document.getElementById('ISC_content').appendChild(buildContentChildNode(keyword, index)) } doIgnore() } else { alert('关键字' + keyword + '已经存在,或者已经存在比它更详细的关键字了') } document.getElementById('filterInput').value = '' } // 敲击回车添加过滤 document.getElementById('filterInput').onkeydown = function(e){ if(e.keyCode === 13){ document.getElementById('filterButton').click() } } } // 可见与不可见间转换 function divVisibleSwitch() { let obj1 = document.getElementById('ISC_input') let obj2 = document.getElementById('ISC_content') if (obj1.style.display === 'none') { obj1.style.display = 'block' obj2.style.display = 'block' return 'block' } else { obj1.style.display = 'none' obj2.style.display = 'none' return 'none' } } // 检查str是否已经在companies中存在,或者str是否包含或被包含于companies的某个值 // return 1 表示之前没有,现在已经添加进去了 // return 0 表示是一个更具体的值 // return -1 表示之前就有,或已有比其更具体值的存在 function addIntoCompanies(str) { if (companies === null) { companies = [] } let len = companies.length for (let i=0; i<len; i++) { if (str === companies[i]) { return -1 } else if (companies[i].indexOf(str) !== -1) { // str比companies[i]的值更具体,那么就需要用str替换对应的值 companies[i] = str document.getElementById('ISC_keyword_' + i).textContent = str return 0 } else if (str.indexOf(companies[i]) !== -1) { return -1 } } companies.push(str) return 1 } // 返回值作为新增节点的id function modifyLocalStorage() { window.localStorage.setItem('companies', JSON.stringify(companies)) return companies.length-1 } // ISC_content区域里面的keyword节点 function buildContentChildNode(val, index) { let childNode = document.createElement('div') childNode.classList.add('ISC_keyword') let id = 'ISC_keyword_' + index childNode.id = id childNode.textContent = val childNode.onclick = function (event) { let tmpIndex = parseInt(event.target.id.split('_')[2]) let tmpKeyword = event.target.innerText event.target.remove() companies.splice(tmpIndex, 1) modifyLocalStorage() correctNodeId(tmpIndex) removeIgnoredTag(tmpKeyword) } return childNode } // 点击删除一个节点后,后续节点的id就需要修正 // id值的最后一部分是代表这个关键字在companies中的序号 // index是刚被删除的节点的序号 function correctNodeId(index) { for (let i = index+1; i<=companies.length; i++) { let node = document.getElementById('ISC_keyword_' + i) if (null !== node) { node.id = 'ISC_keyword_' + (i - 1) } } } // 被移除的关键字对应的条目被恢复可见 function removeIgnoredTag(keyword) { let compDivs = getDivListToIgnore() for (let i=0; i<compDivs.length; i++) { let node = compDivs[i] if (alreadyBeIgnored(node)) { let cName = getRealCompanyName(node) if (cName.indexOf(keyword) !== -1) { node.classList.remove('ISC_ignoreNode') for (let j=0; j<node.children.length; j++) { if (node.children[j].classList.contains('ISC_appendNode')) { node.children[j].remove() } else { node.children[j].classList.remove('ISC_ignoreChildNode') } } } } } } // 入口函数 init()