LinkedIn Job Filter Pro

Advanced filters to toggle promoted, normal, and viewed job listings on LinkedIn job search pages.

// ==UserScript==
// @name         LinkedIn Job Filter Pro
// @namespace    http://tampermonkey.net/
// @version      3.5
// @description  Advanced filters to toggle promoted, normal, and viewed job listings on LinkedIn job search pages.
// @author       yange.xyz
// @match        https://www.linkedin.com/jobs/*
// @grant        none
// @license      MIT
// ==/UserScript==

(function () {
    'use strict';

    const FILTERS = {
        SHOW_ALL: 'SHOW_ALL',
        SHOW_PROMOTED: 'SHOW_PROMOTED',
        SHOW_NORMAL: 'SHOW_NORMAL'
    };

    let activeFilter = FILTERS.SHOW_ALL;
    let onlyUnviewed = false;

    // === Create floating filter panel ===
    const filterPanel = document.createElement('div');
    filterPanel.style.position = 'fixed';
    filterPanel.style.top = '40px';
    filterPanel.style.right = '20px';
    filterPanel.style.zIndex = '10000';
    filterPanel.style.background = 'white';
    filterPanel.style.padding = '8px';
    filterPanel.style.border = '1px solid #ccc';
    filterPanel.style.borderRadius = '8px';
    filterPanel.style.boxShadow = '0 2px 8px rgba(0,0,0,0.15)';
    filterPanel.style.fontFamily = 'Arial, sans-serif';
    filterPanel.style.display = 'flex';
    filterPanel.style.flexDirection = 'column';
    filterPanel.style.gap = '4px';
    filterPanel.style.minWidth = '150px';
    document.body.appendChild(filterPanel);

    // === Create a toggle button to show/hide the whole panel ===
    const toggleBtn = document.createElement('button');
    toggleBtn.innerText = '⚙️';
    toggleBtn.style.position = 'fixed';
    toggleBtn.style.top = '10px'; // Higher than panel to avoid overlap
    toggleBtn.style.right = '20px';
    toggleBtn.style.zIndex = '10001';
    toggleBtn.style.padding = '6px 10px';
    toggleBtn.style.fontSize = '14px';
    toggleBtn.style.border = '1px solid #ccc';
    toggleBtn.style.borderRadius = '50%';
    toggleBtn.style.background = '#f3f3f3';
    toggleBtn.style.cursor = 'pointer';
    toggleBtn.style.boxShadow = '0 2px 6px rgba(0,0,0,0.2)';
    document.body.appendChild(toggleBtn);

    let panelVisible = true;
    toggleBtn.addEventListener('click', () => {
        panelVisible = !panelVisible;
        filterPanel.style.display = panelVisible ? 'flex' : 'none';
    });

    // === Helper to create filter buttons ===
    function createButton(label, onClick, isToggle = false) {
        const btn = document.createElement('button');
        btn.innerText = label;
        btn.style.padding = '6px 8px';
        btn.style.fontSize = '12px';
        btn.style.cursor = 'pointer';
        btn.style.border = '1px solid #0073b1';
        btn.style.borderRadius = '4px';
        btn.style.background = '#0073b1';
        btn.style.color = 'white';
        btn.style.fontWeight = 'bold';
        btn.style.minWidth = '100%';

        btn.addEventListener('click', () => {
            onClick(btn);
        });

        if (isToggle) {
            btn.setAttribute('data-toggle', 'off');
        }

        return btn;
    }

    // === Filter logic ===
    function applyFilter() {
        const cards = document.querySelectorAll('li');
        cards.forEach(card => {
            const text = card.innerText.toLowerCase();
            const isPromoted = text.includes('promoted');
            const isViewed = text.includes('viewed');
            let visible = true;

            if (onlyUnviewed && isViewed) visible = false;

            switch (activeFilter) {
                case FILTERS.SHOW_ALL:
                    visible = visible && true;
                    break;
                case FILTERS.SHOW_PROMOTED:
                    visible = visible && isPromoted;
                    break;
                case FILTERS.SHOW_NORMAL:
                    visible = visible && !isPromoted;
                    break;
            }

            card.style.display = visible ? '' : 'none';
        });
    }

    // === Create buttons ===
    filterPanel.appendChild(createButton('👁 Show All', () => {
        activeFilter = FILTERS.SHOW_ALL;
        applyFilter();
    }));

    filterPanel.appendChild(createButton('💼 Promoted Only', () => {
        activeFilter = FILTERS.SHOW_PROMOTED;
        applyFilter();
    }));

    filterPanel.appendChild(createButton('🔍 Normal Only', () => {
        activeFilter = FILTERS.SHOW_NORMAL;
        applyFilter();
    }));

    const unviewedBtn = createButton('🕵️ Only Unviewed: OFF', (btn) => {
        onlyUnviewed = !onlyUnviewed;
        btn.innerText = onlyUnviewed ? '🕵️ Only Unviewed: ON' : '🕵️ Only Unviewed: OFF';
        applyFilter();
    }, true);
    filterPanel.appendChild(unviewedBtn);

    // === React to dynamic content ===
    const observer = new MutationObserver(applyFilter);
    observer.observe(document.body, { childList: true, subtree: true });
    function highlightPromotedJobs() {
  const cards = document.querySelectorAll("li");

        cards.forEach(card => {
            const spans = card.querySelectorAll("span");
            spans.forEach(span => {
                if (span.textContent.trim().toLowerCase() === "promoted") {
                    span.style.fontWeight = "bold";
                    span.style.color = "red";
                    span.style.fontSize = "1.2em";
                }
            });
        });
    }

    highlightPromotedJobs();

    const sidebarObserver = new MutationObserver(highlightPromotedJobs);
    sidebarObserver.observe(document.body, { childList: true, subtree: true });


    applyFilter(); // Initial run
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址