您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Moves the vote counts in neal.fun/internet-roadtrip from the top right panel to be alongside the arrows, on the wheel, and in the radio
当前为
// ==UserScript== // @name Internet Roadtrip - Combined Votes Counts UI // @description Moves the vote counts in neal.fun/internet-roadtrip from the top right panel to be alongside the arrows, on the wheel, and in the radio // @namespace me.netux.site/user-scripts/internet-roadtrip/combined-votes-counts-ui // @version 1.3.1 // @author netux // @license MIT // @match https://neal.fun/internet-roadtrip/* // @icon https://neal.fun/favicons/internet-roadtrip.png // @run-at document-start // @grant GM_addStyle // @grant GM.getValue // @grant GM.setValue // @require https://cdn.jsdelivr.net/npm/[email protected] // ==/UserScript== /* globals IRF */ (async () => { await IRF.dom.container; GM_addStyle(` .container { & .results { top: 50px; right: 10px; width: fit-content; min-width: 200px; padding: 7px 10px; &::after { /* annoying... */ pointer-events: none; } & .results-content { padding-bottom: 6px; display: none; } & .results-content-toggle-button { width: 100%; height: 0.6rem; margin-block: 0.3rem 0.1rem; background-image: url("https://www.svgrepo.com/show/257732/up-arrow.svg"); background-size: contain; background-position: center; background-repeat: no-repeat; cursor: pointer; display: block; } &.results-content-open { & .results-content-toggle-button { rotate: 180deg; } & .results-content { display: revert; } } } & .options { & .option-votes { position: absolute; font-family: "Roboto", sans-serif; font-size: 12px; color: white; text-shadow: 1px 1px 2px black; bottom: -0.4em; left: 50%; translate: -50% 0; pointer-events: none; white-space: nowrap; } } & .wheel-container { & .wheel-honk-votes { position: absolute; top: 22%; left: 50%; translate: -50%; font-family: "Roboto", sans-serif; font-size: 20px; color: white; text-shadow: 1px 1px 2px black; white-space: nowrap; pointer-events: none; } } } @media screen and (max-width: 900px) { .container { & .results { top: 41px; right: 5px; } } } `); const containerVDOM = await IRF.vdom.container; const resultsEl = await IRF.dom.results; const resultsVDOM = await IRF.vdom.results; const optionsContainerEl = await IRF.dom.options; const wheelContainerEl = await IRF.dom.wheel; const radioEl = await IRF.dom.radio; const wheelHonkVotesEl = document.createElement('span'); const radioSeekVotesTextNode = document.createTextNode('0'); function ensureOptionVotesEl(optionEl) { let votesEl = optionEl._votesEl; if (!votesEl) { votesEl = document.createElement('span'); votesEl.className = 'option-votes'; votesEl.textContent = `0 (0%)`; optionEl.appendChild(votesEl); optionEl._votesEl = votesEl; } return votesEl; } function updateVotes(votes) { const totalVotes = Object.values(votes).reduce((total, count) => total + count, 0); const optionEls = optionsContainerEl.querySelectorAll('.option'); for (const [voteStr, votesCount] of Object.entries(votes)) { const percentageStr = `${totalVotes === 0 ? 0 : Math.floor(votesCount / totalVotes * 100)}%`; switch (voteStr) { case "-2": { wheelHonkVotesEl.textContent = `${votesCount} (${percentageStr})`; break; } case "-1": { radioSeekVotesTextNode.textContent = votesCount; break; } default: { const voteIndex = parseInt(voteStr, 10); const optionEl = optionEls[voteIndex]; if (!optionEl) { continue; } const votesEl = ensureOptionVotesEl(optionEl); votesEl.textContent = `${votesCount} (${percentageStr})`; } } } } { const { set: voteCountsSetter } = Object.getOwnPropertyDescriptor(resultsVDOM.state._props, 'voteCounts'); Object.defineProperty(resultsVDOM.state._props, 'voteCounts', { set(newVoteCounts) { updateVotes(newVoteCounts); return voteCountsSetter.call(this, newVoteCounts); }, configurable: true, enumerable: true, }); } { const optionsContainerMutationObserver = new MutationObserver((records) => { for (const record of records) { if (record.type !== "childList") { continue; } for (const addedOptionEl of record.addedNodes) { if (addedOptionEl.className !== 'option') { continue; } ensureOptionVotesEl(addedOptionEl); } } }); optionsContainerMutationObserver.observe(optionsContainerEl, { childList: true }); const wheelClickArealEl = wheelContainerEl.querySelector('.wheel-click-area'); wheelHonkVotesEl.className = 'wheel-honk-votes'; wheelClickArealEl.appendChild(wheelHonkVotesEl); const radioSeekButtonLabelEl = radioEl.querySelector('.control-button .button-label'); radioSeekButtonLabelEl.append( document.createTextNode(' ('), radioSeekVotesTextNode, document.createTextNode(')'), ); const resultsContentToggleEl = document.createElement('div'); resultsContentToggleEl.className = 'results-content-toggle-button'; resultsContentToggleEl.addEventListener('click', async () => { resultsEl.classList.toggle('results-content-open'); await GM.setValue('results-content-open', resultsEl.classList.contains('results-content-open')); }); if (await GM.getValue('results-content-open')) { resultsEl.classList.toggle('results-content-open', true); } const resultsContentEl = resultsEl.querySelector('.results-content'); resultsContentEl.insertAdjacentElement('afterend', resultsContentToggleEl); } })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址