Rakuten Hover Zoom (overlay safe)

楽天でマウスホバー時に大きい画像を表示(楽天のレイヤー対策)

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         Rakuten Hover Zoom (overlay safe)
// @namespace    https://example.com/
// @version      1.1
// @description  楽天でマウスホバー時に大きい画像を表示(楽天のレイヤー対策)
// @match        https://item.rakuten.co.jp/*
// @match        https://search.rakuten.co.jp/*
// @grant        none
// ==/UserScript==

(function () {
    'use strict';

    // ===== プレビュー用要素作成 =====
    const preview = document.createElement('div');
    Object.assign(preview.style, {
        position: 'fixed',
        pointerEvents: 'none',   // ← レイヤーに干渉されない
        zIndex: '2147483647',    // ← 最前面(楽天のレイヤーより上)
        border: '1px solid #ccc',
        background: '#fff',
        padding: '4px',
        display: 'none',
        boxShadow: '0 2px 8px rgba(0,0,0,0.3)',
    });
    const img = document.createElement('img');
    Object.assign(img.style, {
        maxWidth: '500px',   // サイズ調整
        maxHeight: '500px'
    });
    preview.appendChild(img);
    document.body.appendChild(preview);

    // ===== イベント =====
    const thumbSelector = 'img.image--x5mNi, img[src*="tshop.r10s.jp"]';

    document.addEventListener('mouseover', e => {
        const t = e.target;
        if (t.matches(thumbSelector)) {
            // fitin=275:275 などを削ってオリジナルサイズURLを推測
            let bigUrl = t.src.replace(/\?.*$/, '');
            img.src = bigUrl;
            preview.style.display = 'block';
        }
    });

    document.addEventListener('mousemove', e => {
        if (preview.style.display === 'block') {
            preview.style.top = (e.clientY + 20) + 'px';
            preview.style.left = (e.clientX + 20) + 'px';
        }
    });

    document.addEventListener('mouseout', e => {
        if (e.target.matches(thumbSelector)) {
            preview.style.display = 'none';
        }
    });

    // ===== レイヤーの pointer-events を無効化(任意) =====
    // もし楽天側の拡大レイヤーが残って邪魔な場合
    const observer = new MutationObserver(muts => {
        muts.forEach(m => {
            m.addedNodes.forEach(node => {
                if (node.nodeType === 1 && node.matches('.some-rakuten-overlay-class')) {
                    node.style.pointerEvents = 'none';
                }
            });
        });
    });
    observer.observe(document.body, { childList: true, subtree: true });
})();
// ===== 邪魔な楽天ボタンを透過 =====
function disableRakutenOverlayButton() {
    document.querySelectorAll(
        'button.button--3YE3u' // 質問のHTMLから特定
    ).forEach(btn => {
        // クリック等は残したいなら pointer-events を none
        btn.style.pointerEvents = 'none';
        btn.style.opacity = '0'; // 完全に見えなくする
    });
}

// ページロード後と、動的追加に対応
disableRakutenOverlayButton();
const obs = new MutationObserver(disableRakutenOverlayButton);
obs.observe(document.body, { childList: true, subtree: true });