您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Alphabetizes the company job listings on the Torn job list page with a delay to handle late loading
// ==UserScript== // @name Torn Job List Alphabetizer // @namespace http://tampermonkey.net/ // @version 0.6 // @description Alphabetizes the company job listings on the Torn job list page with a delay to handle late loading // @author dingus // @match https://www.torn.com/joblist.php* // @grant none // ==/UserScript== (function() { 'use strict'; console.log("[Torn Job List Alphabetizer] Script loaded and running at " + new Date().toISOString()); function getElementByXPath(path) { return document.evaluate(path, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; } function sortJobList() { console.log("[Torn Job List Alphabetizer] Attempting to sort job list using XPath..."); const listingsContainer = getElementByXPath('/html/body/div[6]/div/div[2]/div[3]/div[2]/div/div/div[2]/div[2]/ul[2]'); if (!listingsContainer) { console.log("[Torn Job List Alphabetizer] Job listings container not found at the specified XPath."); return false; } if (!listingsContainer.classList.contains('listings')) { console.warn("[Torn Job List Alphabetizer] Element at XPath does not have class='listings'. Found:", listingsContainer); return false; } const jobItems = Array.from(listingsContainer.querySelectorAll('li:not(.clear)')); if (jobItems.length === 0) { console.log("[Torn Job List Alphabetizer] No job items found to sort in the specified <ul>."); return false; } jobItems.sort((a, b) => { const nameA = a.querySelector('span.name')?.textContent.trim().toLowerCase(); const nameB = b.querySelector('span.name')?.textContent.trim().toLowerCase(); if (!nameA || !nameB) { console.error("[Torn Job List Alphabetizer] Could not find span.name in one of the items:", a, b); return 0; } return nameA.localeCompare(nameB); }); listingsContainer.innerHTML = ''; jobItems.forEach(item => listingsContainer.appendChild(item)); const clearItem = document.createElement('li'); clearItem.className = 'clear'; listingsContainer.appendChild(clearItem); console.log("[Torn Job List Alphabetizer] Company job list sorted alphabetically! Found " + jobItems.length + " items."); return true; } window.sortJobList = sortJobList; console.log("[Torn Job List Alphabetizer] Waiting 3 seconds for the job list to load..."); setTimeout(() => { let sorted = sortJobList(); if (!sorted) { console.log("[Torn Job List Alphabetizer] Setting up MutationObserver to watch for the <ul> at the specified XPath..."); const observer = new MutationObserver((mutations, obs) => { const listingsContainer = getElementByXPath('/html/body/div[6]/div/div[2]/div[3]/div[2]/div/div/div[2]/div[2]/ul[2]'); if (listingsContainer) { console.log("[Torn Job List Alphabetizer] ul.listings detected via MutationObserver at the specified XPath!"); const success = sortJobList(); if (success) { obs.disconnect(); } } }); observer.observe(document.body, { childList: true, subtree: true }); } setTimeout(() => { const listingsContainer = getElementByXPath('/html/body/div[6]/div/div[2]/div[3]/div[2]/div/div/div[2]/div[2]/ul[2]'); if (listingsContainer && !listingsContainer.querySelector('li:not(.clear)')) { console.log("[Torn Job List Alphabetizer] Fallback: Retrying sort after 8 seconds..."); sortJobList(); } }, 4000); }, 3000); })();