Price Rounder

Round prices ending in .90 or more to the nearest whole number

当前为 2025-08-14 提交的版本,查看 最新版本

// ==UserScript==
// @name         Price Rounder
// @namespace    http://tampermonkey.net/
// @version      1.1
// @description  Round prices ending in .90 or more to the nearest whole number
// @author       Tempo918
// @match        *://*/*
// @grant        none
// @license MIT
// ==/UserScript==

(function () {
    'use strict';

    const priceRegex = /\b\d{1,3}(?:,\d{3})*(?:\.\d{2})\b/g;

    function isVisible(el) {
        return !!(el.offsetWidth || el.offsetHeight || el.getClientRects().length);
    }

    function roundPricesInNode(node) {
        if (node.nodeType === Node.TEXT_NODE && node.parentElement && isVisible(node.parentElement)) {
            const originalText = node.textContent;
            const newText = originalText.replace(priceRegex, match => {
                let num = parseFloat(match.replace(/,/g, ''));
                let decimal = num % 1;
                if (decimal >= 1) {
                    return Math.ceil(num).toString();
                }
                return match;
            });
            if (newText !== originalText) {
                node.textContent = newText;
            }
        }
    }

    function scanPage() {
        const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT, null, false);
        let node;
        while (node = walker.nextNode()) {
            roundPricesInNode(node);
        }
    }

    window.addEventListener('load', () => {
        scanPage();

        const observer = new MutationObserver(mutations => {
            for (const mutation of mutations) {
                mutation.addedNodes.forEach(node => {
                    if (node.nodeType === Node.TEXT_NODE) {
                        roundPricesInNode(node);
                    } else if (node.nodeType === Node.ELEMENT_NODE) {
                        node.querySelectorAll('*').forEach(el => {
                            el.childNodes.forEach(roundPricesInNode);
                        });
                    }
                });
            }
        });

        observer.observe(document.body, {
            childList: true,
            subtree: true
        });
    });
})();