Amazon Enhancements: Ratings Display and Filtering

Display rating scores and add filtering capabilities on Amazon search results.

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name Amazon Enhancements: Ratings Display and Filtering
// @namespace http://tampermonkey.net/
// @version 2.3
// @description Display rating scores and add filtering capabilities on Amazon search results.
// @author Dave w/ Claudi.ai & ChatGPT
// @match https://*.amazon.com/s?*
// @grant none
// @license MIT
// ==/UserScript==

(function() {
    'use strict';

    let currentFilter = 0;

    // Function to enhance rating display
    const enhanceRatingDisplay = (result) => {
        const ratingElement = result.querySelector('i.a-icon-star-small span.a-icon-alt');
        if (ratingElement && !result.classList.contains('enhanced-rating')) {
            const ratingText = ratingElement.textContent.trim();
            const ratingValue = parseFloat(ratingText.split(' ')[0]);
            const newRatingElement = document.createElement('span');
            newRatingElement.textContent = ratingValue + ' ';
            newRatingElement.style.fontWeight = 'bold';
            newRatingElement.style.color = '#007600'; // Change color if needed
            newRatingElement.style.marginRight = '5px'; // Add some spacing between the ratings
            ratingElement.parentElement.parentElement.insertBefore(newRatingElement, ratingElement.parentElement);
            result.dataset.ratingValue = ratingValue;
            result.classList.add('enhanced-rating');
        }
    };

    // Function to add filter dropdown and refresh icon
    const addFilterDropdown = () => {
        const filterBar = document.createElement('div');
        filterBar.id = 'rating-filter-bar';

        const filterLabel = document.createElement('span');
        filterLabel.textContent = 'Filter by star rating: ';
        filterLabel.style.marginRight = '5px';
        filterBar.appendChild(filterLabel);

        const filterDropdown = document.createElement('select');
        filterDropdown.style.marginRight = '10px';

        // Define dropdown options and their actions
        const filters = [
            { text: 'All', score: 0 },
            { text: '4.9+', score: 4.9 },
            { text: '4.8+', score: 4.8 },
            { text: '4.7+', score: 4.7 },
            { text: '4.6+', score: 4.6 },
            { text: '4.5+', score: 4.5 },
            { text: '4.4+', score: 4.4 },
            { text: '4.3+', score: 4.3 },
            { text: '4.2+', score: 4.2 },
            { text: '4.1+', score: 4.1 }
        ];

        filters.forEach(filter => {
            const option = document.createElement('option');
            option.value = filter.score;
            option.textContent = filter.text;
            filterDropdown.appendChild(option);
        });

        filterDropdown.addEventListener('change', (event) => {
            currentFilter = parseFloat(event.target.value);
            filterResults(currentFilter);
        });

        filterBar.appendChild(filterDropdown);

        const refreshIcon = document.createElement('span');
        refreshIcon.innerHTML = '↻'; // HTML entity for refresh icon
        refreshIcon.style.cursor = 'pointer';
        refreshIcon.style.marginLeft = '5px';
        refreshIcon.addEventListener('click', () => {
            filterResults(currentFilter);
        });

        filterBar.appendChild(refreshIcon);

        // Insert the filter bar at the top of the search results
        const searchResults = document.querySelector('div.s-main-slot.s-result-list.s-search-results.sg-row');
        if (searchResults) {
            searchResults.insertBefore(filterBar, searchResults.firstChild);
        }
    };

    // Function to filter results based on rating score
    const filterResults = (minScore) => {
        const results = document.querySelectorAll('div[data-asin]:not(.s-pagination-container)');
        results.forEach(result => {
            if (!result.querySelector('.s-pagination-container')) {
                const ratingValue = parseFloat(result.dataset.ratingValue);
                result.style.display = ratingValue >= minScore ? '' : 'none';
            }
        });
    };

    // Function to process search results
    const processSearchResults = () => {
        const searchResults = document.querySelectorAll('div[data-asin]:not(.s-pagination-container)');
        searchResults.forEach(result => {
            enhanceRatingDisplay(result);
        });
        filterResults(currentFilter);
    };

    // Throttle function to limit the rate of execution
    const throttle = (func, delay) => {
        let timeoutId = null;
        return (...args) => {
            if (timeoutId === null) {
                func(...args);
                timeoutId = setTimeout(() => {
                    timeoutId = null;
                }, delay);
            }
        };
    };

    // Throttled version of processSearchResults
    const throttledProcessSearchResults = throttle(processSearchResults, 500);

    // Observe changes in the search results
    const observeSearchResults = () => {
        const searchResultsContainer = document.querySelector('div.s-main-slot.s-result-list.s-search-results.sg-row');
        if (searchResultsContainer) {
            const observer = new MutationObserver(throttledProcessSearchResults);
            observer.observe(searchResultsContainer, {
                childList: true,
                subtree: true
            });
        }
    };

    // Initialize the script
    const init = () => {
        addFilterDropdown();
        processSearchResults();
        observeSearchResults();
    };

    // Run the script when the page has loaded
    window.addEventListener('load', init);
})();