您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Toggle all item listings anonymous ON/OFF while keeping manual control
// ==UserScript== // @name Shadowlister(Torn Auto-Anon Toggle) // @namespace http://tampermonkey.net/ // @version 1.4 // @description Toggle all item listings anonymous ON/OFF while keeping manual control // @match https://www.torn.com/page.php?sid=ItemMarket* // @grant none // @run-at document-idle // ==/UserScript== (function () { 'use strict'; let autoAnon = true; // Create container for button with drag header const buttonContainer = document.createElement('div'); Object.assign(buttonContainer.style, { position: 'fixed', top: '50%', left: '10px', transform: 'translateY(-50%)', zIndex: '9999', borderRadius: '6px', overflow: 'hidden', opacity: 0.9, userSelect: 'none', border: '2px solid #0f0', }); // Create drag header const dragHeader = document.createElement('div'); dragHeader.textContent = '⋮⋮'; Object.assign(dragHeader.style, { backgroundColor: '#0f0', color: '#222', padding: '2px 12px', fontSize: '10px', textAlign: 'center', cursor: 'grab', fontWeight: 'bold', lineHeight: '1', }); // Create toggle button const toggleBtn = document.createElement('button'); toggleBtn.textContent = 'Auto-Anon: ON'; Object.assign(toggleBtn.style, { backgroundColor: '#222', color: '#0f0', border: 'none', padding: '8px 12px', fontSize: '14px', cursor: 'pointer', width: '100%', display: 'block', }); toggleBtn.onclick = () => { autoAnon = !autoAnon; toggleBtn.textContent = `Auto-Anon: ${autoAnon ? 'ON' : 'OFF'}`; toggleBtn.style.color = autoAnon ? '#0f0' : '#f00'; buttonContainer.style.borderColor = autoAnon ? '#0f0' : '#f00'; dragHeader.style.backgroundColor = autoAnon ? '#0f0' : '#f00'; applyToAllVisible(); }; // Assemble the container buttonContainer.appendChild(dragHeader); buttonContainer.appendChild(toggleBtn); // Make container draggable using the proven approach makeDraggable(buttonContainer, dragHeader); document.body.appendChild(buttonContainer); // Draggable functionality (based on working example) function makeDraggable(element, dragHandle) { let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0; dragHandle.onmousedown = dragMouseDown; dragHandle.ontouchstart = dragTouchStart; function dragMouseDown(e) { e = e || window.event; e.preventDefault(); pos3 = e.clientX; pos4 = e.clientY; document.onmouseup = closeDragElement; document.onmousemove = elementDrag; dragHandle.style.cursor = 'grabbing'; } function dragTouchStart(e) { const touch = e.touches[0]; pos3 = touch.clientX; pos4 = touch.clientY; document.ontouchend = closeDragElement; document.ontouchmove = elementTouchDrag; dragHandle.style.cursor = 'grabbing'; } function elementDrag(e) { e = e || window.event; e.preventDefault(); pos1 = pos3 - e.clientX; pos2 = pos4 - e.clientY; pos3 = e.clientX; pos4 = e.clientY; const newTop = element.offsetTop - pos2; const newLeft = element.offsetLeft - pos1; // Keep within viewport bounds const maxX = window.innerWidth - element.offsetWidth; const maxY = window.innerHeight - element.offsetHeight; element.style.top = Math.max(0, Math.min(newTop, maxY)) + "px"; element.style.left = Math.max(0, Math.min(newLeft, maxX)) + "px"; element.style.transform = 'none'; } function elementTouchDrag(e) { const touch = e.touches[0]; pos1 = pos3 - touch.clientX; pos2 = pos4 - touch.clientY; pos3 = touch.clientX; pos4 = touch.clientY; const newTop = element.offsetTop - pos2; const newLeft = element.offsetLeft - pos1; // Keep within viewport bounds const maxX = window.innerWidth - element.offsetWidth; const maxY = window.innerHeight - element.offsetHeight; element.style.top = Math.max(0, Math.min(newTop, maxY)) + "px"; element.style.left = Math.max(0, Math.min(newLeft, maxX)) + "px"; element.style.transform = 'none'; } function closeDragElement() { document.onmouseup = null; document.onmousemove = null; document.ontouchend = null; document.ontouchmove = null; dragHandle.style.cursor = 'grab'; } } // Tick/Untick all visible checkboxes function applyToAllVisible() { const allBoxes = document.querySelectorAll('input[id^="itemRow-incognitoCheckbox-"]'); allBoxes.forEach(box => { if (autoAnon && !box.checked) { box.click(); } else if (!autoAnon && box.checked) { box.click(); } }); } // Observer for new rows const observer = new MutationObserver(mutations => { for (let mutation of mutations) { for (let node of mutation.addedNodes) { if (!(node instanceof HTMLElement)) continue; const checkboxes = node.querySelectorAll?.('input[id^="itemRow-incognitoCheckbox-"]') || []; checkboxes.forEach(checkbox => { if (autoAnon && !checkbox.checked) { checkbox.click(); } else if (!autoAnon && checkbox.checked) { checkbox.click(); } }); } } }); function initObserver() { if (location.hash.startsWith('#/addListing')) { observer.observe(document.body, { childList: true, subtree: true }); applyToAllVisible(); // First batch } } window.addEventListener('hashchange', initObserver); window.addEventListener('load', initObserver); initObserver(); })();