您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Mutes downvoted items. Hide specific merchants
当前为
// ==UserScript== // @name HUDK - UX tweaks // @namespace http://tampermonkey.net/ // @version 0.2.1 // @description Mutes downvoted items. Hide specific merchants // @author thedrunkendev // @match https://www.hotukdeals.com/* // @icon https://www.google.com/s2/favicons?sz=64&domain=hotukdeals.com // @run-at document-start // @grant GM_getValue // @grant GM_setValue // ==/UserScript== /* global waitForKeyElements */ (function() { 'use strict'; console.log("Injecting Userscript") let hiddenMerchants = GM_getValue("gm_hiddenmerchants") || []; console.log("Found hiddent merchants:", hiddenMerchants) // Hide downvoted waitForKeyElements(".vote-box > .bg--color-grey .icon--minus", (el) => { console.log(el) el.closest(".threadGrid").style.opacity = 0.5; }, false, 1_000); // Add a hide merchant button waitForKeyElements("button.cept-off", (el) => { const merchant = el.closest(".threadGrid").querySelector(".cept-merchant-name"); const merchantIsHidden = hiddenMerchants.includes(merchant?.innerText); if (merchant && merchantIsHidden){ hideMerchant(el, merchant.innerText) } else{ insert(el); } }, false, 1_000); function insert(el) { var textEl = document.createElement("button") textEl.innerText = "hide merchant"; textEl.className = el.className.replace("cept-off", "btn btn--mode-boxSec"); textEl.onclick = (clickedEl) => { const merchant = el.closest(".threadGrid").querySelector(".cept-merchant-name").innerText; hiddenMerchants.push(merchant); GM_setValue("gm_hiddenmerchants", hiddenMerchants); // Hide button & thread clickedEl.target.style.display="none"; hideMerchant(clickedEl.target, merchant); }; el.insertAdjacentElement("beforebegin", textEl); } function hideMerchant(el, merchantName){ const thread = el.closest(".threadGrid"); thread.style.opacity = 0.8; thread.style.justifyContent="space-between"; thread.style.display="flex"; thread.innerHTML = `<div><span class="cept-merchant-name">${merchantName}</span> is hidden.</div>`; var textEl = document.createElement("button") textEl.innerText = "Undo"; textEl.className = el.className="btn btn--mode-boxSec"; textEl.onclick = (clickedEl) => { const merchant = thread.querySelector(".cept-merchant-name").innerText; hiddenMerchants=hiddenMerchants.filter(x=> x!=merchant); console.log(hiddenMerchants) GM_setValue("gm_hiddenmerchants", hiddenMerchants); // Hide button & thread clickedEl.target.style.display="none"; // TODO - show the deal? }; thread.appendChild(textEl); } })(); /** * A utility function for userscripts that detects and handles AJAXed content. * * Usage example: * * function callback(domElement) { * domElement.innerHTML = "This text inserted by waitForKeyElements()."; * } * * waitForKeyElements("div.comments", callback); * // or * waitForKeyElements(selectorFunction, callback); * * @param {(string|function)} selectorOrFunction - The selector string or function. * @param {function} callback - The callback function; takes a single DOM element as parameter. * If returns true, element will be processed again on subsequent iterations. * @param {boolean} [waitOnce=true] - Whether to stop after the first elements are found. * @param {number} [interval=300] - The time (ms) to wait between iterations. * @param {number} [maxIntervals=-1] - The max number of intervals to run (negative number for unlimited). */ function waitForKeyElements(selectorOrFunction, callback, waitOnce, interval, maxIntervals) { if (typeof waitOnce === "undefined") { waitOnce = true; } if (typeof interval === "undefined") { interval = 300; } if (typeof maxIntervals === "undefined") { maxIntervals = -1; } var targetNodes = (typeof selectorOrFunction === "function") ? selectorOrFunction() : document.querySelectorAll(selectorOrFunction); var targetsFound = targetNodes && targetNodes.length > 0; if (targetsFound) { targetNodes.forEach(function(targetNode) { var attrAlreadyFound = "data-userscript-alreadyFound"; var alreadyFound = targetNode.getAttribute(attrAlreadyFound) || false; if (!alreadyFound) { var cancelFound = callback(targetNode); if (cancelFound) { targetsFound = false; } else { targetNode.setAttribute(attrAlreadyFound, true); } } }); } if (maxIntervals !== 0 && !(targetsFound && waitOnce)) { maxIntervals -= 1; setTimeout(function() { waitForKeyElements(selectorOrFunction, callback, waitOnce, interval, maxIntervals); }, interval); } }