您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
PoE trade cluster jewel starting passives filter
// ==UserScript== // @name PoE Cluster Filter // @description PoE trade cluster jewel starting passives filter // @version 1.0.0 // @author ArnoldsK // @namespace https://arnoldsk.lv // @match https://*.pathofexile.com/trade/search/* // @icon https://www.google.com/s2/favicons?domain=pathofexile.com // @license MIT // @grant none // ==/UserScript== // ############################################################################# // Global elements // ############################################################################# const getResultsEl = () => document.querySelector('#trade .resultset') const getSearchBtnEl = () => document.querySelector('#trade .btn.search-btn') const clusterFilterApp = ( state = { masteries: [], hidden: 0, }, ) => { // ############################################################################# // Add nav tab // ############################################################################# const tabsEl = document.querySelector('.nav.nav-tabs.account') const tabEl = document.createElement('li') tabEl.classList.add('menu-settings', 'menu-clusters') tabEl.innerHTML = ` <a href="javascript:void(0)"> <span>Clusters</span> </a> ` tabsEl.appendChild(tabEl) // ############################################################################# // Add config // ############################################################################# const cfgEl = document.createElement('div') cfgEl.style.cssText = ` display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0 0 0 / 0.5); ` const cfgBodyEl = document.createElement('div') cfgBodyEl.style.cssText = ` position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: #000; padding: 16px; border: 1px solid #5a3806; display: flex; flex-direction: column; align-items: center; gap: 8px; ` const txtEl = document.createElement('textarea') txtEl.classList.add('form-control') txtEl.placeholder = [ 'Add mastery names that should be the first passives before the jewel sockets. Separate each one by a new line. For example:', '', 'Martial Prowess', 'Fuel the Fight', ].join('\n') txtEl.style.cssText = ` width: 30vmin; min-height: 13vmin; resize: vertical; ` const ctlEl = document.createElement('div') ctlEl.classList.add('controls') ctlEl.style.cssText = ` width: 100%; display: flex; justify-content: center; ` const filterBtnEl = document.createElement('button') filterBtnEl.classList.add('btn', 'search-btn', 'cluster-filter-btn') filterBtnEl.innerHTML = ` <span>Filter</span> ` const resetBtnEl = document.createElement('button') resetBtnEl.classList.add('btn', 'clear-btn', 'cluster-reset-btn') resetBtnEl.innerHTML = ` <span>Reset</span> ` const infoBtnEl = document.createElement('button') infoBtnEl.classList.add('btn', 'clear-btn', 'cluster-info-btn') infoBtnEl.style.cssText = ` min-width: auto; ` infoBtnEl.innerHTML = ` <span>?</span> ` const btnGrpEl = document.createElement('div') btnGrpEl.style.cssText = ` width: 100%; display: flex; justify-content: center; gap: 8px; ` btnGrpEl.appendChild(filterBtnEl) btnGrpEl.appendChild(resetBtnEl) btnGrpEl.appendChild(infoBtnEl) cfgBodyEl.appendChild(txtEl) cfgBodyEl.appendChild(btnGrpEl) ctlEl.appendChild(cfgBodyEl) cfgEl.appendChild(ctlEl) document.querySelector('#trade').appendChild(cfgEl) // ############################################################################# // Observer for new items // ############################################################################# const observer = new MutationObserver(async (mutationList) => { // No masteries if (!state.masteries.length) return // Has new items const hasAddedNodes = mutationList.some( (mutation) => !!mutation.addedNodes.length, ) if (hasAddedNodes) { filterClusters() } }) // ############################################################################# // Handlers // ############################################################################# const setHidden = (hidden) => { state.hidden = hidden tabEl.querySelector('span').innerText = hidden ? `Clusters (${hidden} hidden)` : 'Clusters' } const toggleConfig = () => { const isVisible = cfgEl.style.display !== 'none' cfgEl.style.display = isVisible ? 'none' : 'block' } const filterClusters = () => { // No masteries if (!state.masteries.length) return // Filter const cntEls = [...getResultsEl().querySelectorAll('.content')] for (const cntEl of cntEls) { // Skip the already hidden const rowEl = cntEl.closest('.row') if (!rowEl || rowEl.style.display === 'none') continue // Hide if has matched masteries const noteEls = [...cntEl.querySelectorAll('.notableProperty')] if (noteEls.length < 2) continue const names = noteEls.map( (el) => el.querySelector('.colourAugmented').innerText, ) const filter = (name) => state.masteries.some( (mastery) => mastery.toLocaleLowerCase() === name.toLocaleLowerCase(), ) const firstName = names[0] const lastName = names[names.length - 1] // Match const findFn = state.masteries.length === 1 ? 'some' : 'every' const hasMatch = names.length === 2 ? [firstName][findFn](filter) : [firstName, lastName][findFn](filter) if (!hasMatch) { rowEl.style.display = 'none' setHidden(state.hidden + 1) } } } const resetClusters = () => { setHidden(0) const resultsEl = getResultsEl() if (resultsEl) { resultsEl.querySelectorAll('.row').forEach((el) => { el.style.display = 'flex' }) } } // ############################################################################# // Events and data // ############################################################################# tabEl.addEventListener('click', () => { toggleConfig() }) filterBtnEl.addEventListener('click', () => { const masteries = txtEl.value .split('\n') .map((el) => el.trim()) .filter((el) => !!el) state.masteries = masteries resetClusters() if (masteries.length) { localStorage.setItem('poe-clusters-filter', JSON.stringify(masteries)) filterClusters() observer.observe(getResultsEl(), { childList: true, }) } else { localStorage.removeItem('poe-clusters-filter') observer.disconnect() } toggleConfig() }) getSearchBtnEl().addEventListener('click', () => { resetClusters() observer.disconnect() }) resetBtnEl.addEventListener('click', () => { toggleConfig() resetClusters() observer.disconnect() }) infoBtnEl.addEventListener('click', () => { window.open('https://imgur.com/a/ELSXIW7') }) // ############################################################################# // Restore local storage if set // ############################################################################# const storedMasteries = localStorage.getItem('poe-clusters-filter') if (storedMasteries) { const masteries = JSON.parse(storedMasteries) txtEl.value = masteries.join('\n') } } window.addEventListener('load', () => { // Scuffed solution for content load check const loadedInterval = setInterval(() => { if (!getSearchBtnEl()) return clearInterval(loadedInterval) clusterFilterApp() }, 100) })
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址