Greasy Fork 支持简体中文。

更新情報にサムネ追加

更新情報エリアにリンクのサムネイルを追加します

// ==UserScript==
// @name         更新情報にサムネ追加
// @namespace    http://tampermonkey.net/
// @version      1.0
// @description  更新情報エリアにリンクのサムネイルを追加します
// @author       adsamalu4kia 
// @license      adsamalu4kia 
// @match        https://www.megahit.co.jp/category_product.php?search_category_id=2*
// @grant        GM_xmlhttpRequest
// @connect      www.megahit.co.jp
// ==/UserScript==

(function() {
    'use strict';

    const updateInfoArea = document.getElementById('updateinfo_area');
    const cache = {};
    const MAX_CONCURRENT_REQUESTS = 5;
    let currentRequests = 0;
    let processedLinks = 0;

    const indicatorContainer = document.createElement('div');
    const indicator = document.createElement('div');
    const statusText = document.createElement('span');

    // ローディングインジケーターの設定
    const style = document.createElement('style');
    style.textContent = `
        @keyframes spin {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
        }
        .loading-indicator {
            display: none;
            border: 8px solid #f3f3f3;
            border-top: 8px solid #3498db;
            border-radius: 50%;
            width: 30px;
            height: 30px;
            animation: spin 1s linear infinite;
            margin-right: 10px;
        }
    `;
    document.head.appendChild(style);

    indicator.className = 'loading-indicator';
    indicatorContainer.appendChild(indicator);
    indicatorContainer.appendChild(statusText);
    updateInfoArea.insertBefore(indicatorContainer, updateInfoArea.firstChild);

    if (updateInfoArea) {
        const links = updateInfoArea.querySelectorAll('a');
        const totalLinks = links.length;

        function processLink(link) {
            const url = link.href;
            indicator.style.display = 'block';
            statusText.innerText = 'サムネ取得中';
            statusText.style.display = 'inline';

            GM_xmlhttpRequest({
                method: "GET",
                url: url,
                onload: function(response) {
                    currentRequests--;
                    if (response.status === 200) {
                        const parser = new DOMParser();
                        const doc = parser.parseFromString(response.responseText, 'text/html');
                        const productCodeElement = doc.getElementById('product_code_default');

                        if (productCodeElement) {
                            const productCode = productCodeElement.textContent.trim();
                            let thumbnailUrl = cache[productCode] || `https://www.megahit.co.jp/upload/save_image/${productCode}_01.jpg`;
                            cache[productCode] = thumbnailUrl;

                            GM_xmlhttpRequest({
                                method: "HEAD",
                                url: thumbnailUrl,
                                onload: function(headResponse) {
                                    processedLinks++;
                                    if (headResponse.status === 200) {
                                        const img = document.createElement('img');
                                        img.src = thumbnailUrl;
                                        img.alt = 'Thumbnail';
                                        img.style.width = '100px';
                                        img.style.marginRight = '10px';
                                        link.parentNode.insertBefore(img, link);
                                    }
                                    checkCompletion();
                                    processNextLink();
                                },
                                onerror: function(error) {
                                    console.error('サムネイル確認リクエストエラー:', error);
                                    processedLinks++;
                                    checkCompletion();
                                    processNextLink();
                                }
                            });
                        } else {
                            console.log('商品コードが見つかりませんでした。');
                            processedLinks++;
                            checkCompletion();
                            processNextLink();
                        }
                    } else {
                        console.error('リクエストに失敗しました:', response.status);
                        processedLinks++;
                        checkCompletion();
                        processNextLink();
                    }
                },
                onerror: function(error) {
                    console.error('リクエストエラー:', error);
                    currentRequests--;
                    processedLinks++;
                    checkCompletion();
                    processNextLink();
                }
            });
        }

        function processNextLink() {
            if (currentRequests < MAX_CONCURRENT_REQUESTS && processedLinks < totalLinks) {
                const nextLink = links[processedLinks];
                if (nextLink) {
                    currentRequests++;
                    processLink(nextLink);
                }
            }
        }

        function checkCompletion() {
            if (processedLinks === totalLinks && currentRequests === 0) {
                console.log('すべてのリンクが処理されました。');
                indicator.style.display = 'none';
                statusText.style.display = 'none';
            }
        }

        processNextLink();
    }
})();