Greasy Fork is available in English.

职位搜索助手

能够自动过滤职位搜索页面不想看到的公司,给公司添加标签来帮助记忆特点,只支持智联招聘和前程无忧

// ==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();