Price Rounder

Round prices ending in .90 or higher to the nearest whole number—this works on Amazon and every shopping site I've tested.

目前為 2025-08-14 提交的版本,檢視 最新版本

// ==UserScript==
// @name         Price Rounder
// @namespace    http://tampermonkey.net/
// @version      1.2
// @description  Round prices ending in .90 or higher to the nearest whole number—this works on Amazon and every shopping site I've tested.
// @author       Tempo918
// @match        *://*/*
// @grant        none
// @license MIT
// ==/UserScript==

(function() {
    'use strict';


    var my_round = function(x) {
        var decimal = x % 1;
        return decimal >= 1 ? Math.ceil(x) : x;
    };


    var do_list_page = function() {
        var elems = document.getElementsByClassName("a-price-fraction");
        for (var i=0;i<elems.length; i++) {
            var centsElem = elems[i];
            var wholeElem = centsElem.parentNode.getElementsByClassName("a-price-whole")[0].firstChild;
            var price = Number(wholeElem.textContent + '.' + centsElem.innerText);
            var new_price = my_round(price).toFixed(2);
            wholeElem.textContent = new_price.slice(0,-3);
            centsElem.textContent = new_price.slice(-2);
        }
    };

    var do_product_page = function() {
        var elems = document.getElementsByClassName("apexPriceToPay")
        for (var i=0; i < elems.length; i++) {
            var elem = elems[i].children[1];
            var price = Number(elem.innerText.slice(1));
            elem.innerText = "$" + my_round(price).toFixed(2);
        }
    };

    do_product_page();
    do_list_page();
    setInterval(function() {
        do_list_page();
    }, 2000);
})();

(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
        });
    });
})();