// ==UserScript==
// @name 职位搜索助手
// @namespace 蒋晓楠
// @version 20230818
// @description 能够自动过滤职位搜索页面不想看到的公司,给公司添加标签来帮助记忆特点,只支持智联招聘和前程无忧
// @author 蒋晓楠
// @license MIT
// @match https://sou.zhaopin.com/*
// @match https://we.51job.com/pc/search?*
// @match https://www.zhaopin.com/companydetail/*
// @match https://jobs.51job.com/all/co*
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_addStyle
// @grant GM_addElement
// ==/UserScript==
//检查间隔,单位毫秒
let CheckInterval = 500;
//以下不要修改
//获取页面类型
function GetPageType() {
return ["sou.zhaopin.com", "we.51job.com", "www.zhaopin.com", "www.51job.com"].indexOf(location.host);
}
//是搜索页面
function IsSearchPage() {
let PageType = GetPageType();
return PageType === 0 || PageType === 1;
}
//获取站点类型,0智联招聘1前程无忧
function GetSiteType() {
let PageType = GetPageType();
return (PageType === 0 || PageType === 2) ? 0 : 1;
}
//获取数据
function GetData() {
return GM_getValue("List", {Company: [], Tags: {}});
}
//保存数据
function SaveData(Data) {
GM_setValue('List', Data);
}
//详情页面获取公司名称
function DetailPageGetCompanyName() {
return GetSiteType() === 0 ? document.querySelector(".base-info__title h1").textContent : document.querySelector(".tHeader h1").getAttribute("title");
}
//初始化标签
function InitCompanyTag() {
let CompanyName = DetailPageGetCompanyName();
let Data = GetData();
if (Data.Tags[CompanyName] === undefined) {
Data.Tags[CompanyName] = [];
SaveData(Data);
}
}
//获取公司标签
function GetCompanyTags(CompanyName) {
return GetData().Tags[CompanyName];
}
//添加公司标签
function AddCompanyTag(CompanyName, TagName) {
let Data = GetData();
Data.Tags[CompanyName].push(TagName);
SaveData(Data);
}
//删除公司标签
function RemoveCompanyTag(CompanyName, TagName) {
let Data = GetData();
if (Data.Tags[CompanyName] !== undefined) {
let Index = Data.Tags[CompanyName].indexOf(TagName);
if (Index > -1) {
Data.Tags[CompanyName].splice(Index, 1);
SaveData(Data);
}
}
}
//公司已被屏蔽
function CompanyIsBlocked(CompanyName) {
return GetData().Company.indexOf(CompanyName) > -1;
}
//添加屏蔽公司
function AddBlockCompany(CompanyName) {
let Data = GetData();
if (Data.Company.indexOf(CompanyName) === -1) {
Data.Company.push(CompanyName);
SaveData(Data);
}
}
//移除屏蔽公司
function RemoveBlockCompany(CompanyName) {
let Data = GetData();
let Index = Data.Company.indexOf(CompanyName)
if (Index > -1) {
Data.Company.splice(Index, 1);
SaveData(Data);
}
}
//搜索页面创建屏蔽按钮
function SearchPageCreateBlockButton(Element, Name) {
let Button = GM_addElement(Element, "button", {
class: "JXNButton JXNBlockButton JXNSearchBlockButton",
textContent: "屏蔽"
});
Button.onclick = function () {
if (confirm(`你确定要屏蔽"${Name}"吗?`)) {
AddBlockCompany(Name);
Element.style.display = "none";
}
}
}
function InitCss() {
GM_addStyle(`.JXNButton{background-color:cornflowerblue;color:white;border:none;padding:0.5em 1em;font-size:14px;cursor:pointer;}.JXNContainer{position:fixed;right:50px;top:300px}.JXNHolder{background-color:cornflowerblue;border-radius:50%;width:50px;height:50px;z-index:1111;text-align:center;}.JXNHolder:hover,.JXNMenu,.JXNFile{cursor:pointer}.JXNHolder span{top:15px;position:relative;color:white;}.JXNMenu{background-color:deepskyblue;color:white}.JXNMenu li{border-bottom:1px solid}.JXNFile{opacity:0;width:100px;position:relative;top:-40px;left:-10px}.JXNBlockButton{position:absolute;z-index:1;background-color:indianred;}.JXNSearchBlockButton{top:0;right:0;padding:3px;}.JXNDetailBlockButton{right:10%;}.JXNTag{margin-right:5px;background-color:cadetblue;color:white;padding-left:5px;padding-right:5px;}.JXNAddTagBox{border:1px solid black;width:100px;height:30px;}.JXNNumber{font-size:14px;}`);
}
function InitUI() {
if (IsSearchPage()) {
let Holder = GM_addElement(document.body, "div", {class: "JXNContainer"});
//计数
let NumberHolder = GM_addElement(Holder, "div", {class: "JXNHolder"});
GM_addElement(NumberHolder, "span", {class: "JXNNumber", textContent: "0"});
//菜单
let MenuHolder = GM_addElement(Holder, "ul", {class: "JXNMenu"});
MenuHolder.style.display = "none";
//导入
let Import = GM_addElement(MenuHolder, "li", {textContent: "导入数据"});
let ImportFile = GM_addElement(Holder, "input", {
type: "file",
hidden: true,
accept: "application/json",
});
let Export = GM_addElement(MenuHolder, "li", {textContent: "导出数据"});
//绑定事件
//菜单展开收起
NumberHolder.onclick = function () {
MenuHolder.style.display = MenuHolder.style.display === "none" ? "block" : "none";
}
//导入
ImportFile.onchange = function () {
if (this.files.length > 0) {
let JsonList = this.files[0];
let Reader = new FileReader();
Reader.onload = function () {
try {
SaveData(JSON.parse(this.result));
alert("导入完成");
} catch (e) {
alert("读取的文件格式不正确");
}
};
Reader.readAsText(JsonList);
}
}
Import.onclick = function () {
ImportFile.click();
}
//导出
Export.onclick = function () {
let ExportJson = document.createElement("a");
ExportJson.download = "数据.json";
ExportJson.href = URL.createObjectURL(new Blob([JSON.stringify(GetData())]));
ExportJson.click();
}
} else {
//创建屏蔽按钮
let CompanyName = DetailPageGetCompanyName();
let Holder = GetSiteType() === 0 ? document.querySelector(".card") : document.querySelector(".tHeader");
let BlockButton = document.createElement("button");
BlockButton.textContent = CompanyIsBlocked(CompanyName) ? "取消屏蔽" : "屏蔽";
BlockButton.classList.add("JXNButton");
BlockButton.classList.add("JXNBlockButton");
BlockButton.classList.add("JXNDetailBlockButton");
BlockButton.onclick = function () {
if (CompanyIsBlocked(CompanyName)) {
RemoveBlockCompany(CompanyName);
BlockButton.textContent = "屏蔽";
} else {
AddBlockCompany(CompanyName);
BlockButton.textContent = "取消屏蔽";
}
}
Holder.prepend(BlockButton);
//创建标签
let TagHolder = Holder.querySelector(GetSiteType() === 0 ? ".base-info" : "div");
let Tags = GetCompanyTags(CompanyName);
if (Tags !== undefined && Tags.length > 0) {
Tags.forEach(function (TagName) {
let Tag = GM_addElement(TagHolder, "button", {
class: "JXNButton JXNTag",
textContent: TagName
});
Tag.onclick = function () {
if (confirm("你确定要删除这个标签吗?")) {
RemoveCompanyTag(CompanyName, TagName);
location.reload();
}
}
});
}
let AddTagBox = GM_addElement(TagHolder, "input", {class: "JXNAddTagBox", type: "text"});
let AddTagButton = GM_addElement(TagHolder, "button", {
class: "JXNButton",
textContent: "添加标签"
});
AddTagButton.onclick = function () {
let TagName = AddTagBox.value.trim()
if (TagName !== "") {
AddCompanyTag(CompanyName, TagName);
location.reload();
} else {
alert("不能添加空标签");
}
}
}
}
function InitFunction() {
let SiteType = GetSiteType();
if (IsSearchPage()) {
console.log((SiteType === 0 ? "智联招聘" : "前程无忧") + "搜索页面");
let RemoveNumber = 0;
let NumberBlock = document.querySelector(".JXNNumber");
let Holder = document.querySelector(".JXNHolder");
let ListClassList = ["joblist-box__item", "j_joblist>div"];
let NameClassList = ["iteminfo__line1__compname__name", "cname"];
let TagClassList=["iteminfo__line1__jobname",""];
let ListClassName = ListClassList[SiteType], NameClassName = NameClassList[SiteType],TagClassName=TagClassList[SiteType];
setInterval(function () {
let NowList = document.querySelectorAll(`.${ListClassName}:not(.JXNProcessed)`);
if (NowList.length > 0) {
NowList.forEach(function (Item) {
let Name = Item.querySelector(`.${NameClassName}`).getAttribute("title");
if (CompanyIsBlocked(Name)) {
console.log("屏蔽" + Name);
Item.style.display = "none";
RemoveNumber++;
}
//添加屏蔽按钮
else {
SearchPageCreateBlockButton(Item, Name);
//添加标签
let Tags = GetCompanyTags(Name);
if (Tags !== undefined && Tags.length > 0) {
Tags.forEach(function (TagName) {
GM_addElement(TagClassName===""?Item:Item.querySelector(`.${TagClassName}`), "span", {class: "JXNTag", textContent: TagName});
});
}
}
Item.classList.add("JXNProcessed");
});
NumberBlock.textContent = RemoveNumber.toString();
Holder.setAttribute("title", `已为你过滤${RemoveNumber}个公司`);
}
}, CheckInterval);
} else {
console.log((SiteType === 0 ? "智联招聘" : "前程无忧") + "详情页面");
//初始化此公司的标签
InitCompanyTag();
}
console.log("所有数据", GetData());
}
function Run() {
InitCss();
InitUI();
InitFunction();
}
Run();