Greasy Fork is available in English.
Load Amazon product pages and display price in a tooltip
当前为
// ==UserScript==
// @name Amazon Product Price Loader (Optimized)
// @namespace http://tampermonkey.net/
// @version 1.0
// @description Load Amazon product pages and display price in a tooltip
// @license MIT https://opensource.org/licenses/MIT
// @match https://sellercentral.amazon.com/*
// @match https://sellercentral.amazon.co.uk/*
// @match https://sellercentral.amazon.de/*
// @match https://sellercentral.amazon.fr/*
// @match https://sellercentral.amazon.it/*
// @match https://sellercentral.amazon.es/*
// @match https://sellercentral.amazon.ca/*
// @match https://sellercentral.amazon.com.mx/*
// @match https://sellercentral.amazon.com.br/*
// @match https://sellercentral.amazon.co.jp/*
// @match https://sellercentral.amazon.in/*
// @match https://sellercentral.amazon.com.au/*
// @grant GM_xmlhttpRequest
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_addStyle
// @run-at document-end
// ==/UserScript==
(function() {
'use strict';
// Create and append tooltip element
const tooltip = document.createElement('div');
tooltip.id = 'priceTooltip';
GM_addStyle(`
#priceTooltip {
position: fixed;
background-color: #fff;
border: 1px solid #ddd;
padding: 5px 10px;
border-radius: 4px;
box-shadow: 0 2px 5px rgba(0,0,0,0.2);
display: none;
z-index: 10000;
font-family: Arial, sans-serif;
font-size: 14px;
}
`);
document.body.appendChild(tooltip);
let tooltipTimeout;
const priceCache = {};
function extractPrice(html) {
const parser = new DOMParser();
const doc = parser.parseFromString(html, 'text/html');
const priceSelectors = [
'.a-price .a-offscreen',
'#priceblock_ourprice',
'#priceblock_dealprice',
'.a-price-whole',
'.a-offscreen'
];
for (let selector of priceSelectors) {
const priceElement = doc.querySelector(selector);
if (priceElement) {
return priceElement.textContent.trim();
}
}
return null;
}
async function loadProductPage(url) {
if (priceCache[url]) {
return Promise.resolve(priceCache[url]);
}
return new Promise((resolve, reject) => {
GM_xmlhttpRequest({
method: 'GET',
url: url,
onload: function(response) {
if (response.status === 200) {
const price = extractPrice(response.responseText);
priceCache[url] = price;
resolve(price);
} else {
reject('Failed to load page');
}
},
onerror: function(error) {
reject(error);
}
});
});
}
function debounce(func, wait) {
let timeout;
return function(...args) {
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(this, args), wait);
};
}
const handleMouseover = debounce(function(e) {
const link = e.target.closest('a[href*="/dp/"], a[href*="/product/"]');
if (link) {
const url = link.href;
clearTimeout(tooltipTimeout);
tooltipTimeout = setTimeout(() => {
tooltip.textContent = 'Loading price...';
tooltip.style.display = 'block';
updateTooltipPosition(e);
loadProductPage(url)
.then(price => {
if (price) {
tooltip.textContent = `Price: ${price}`;
} else {
tooltip.textContent = 'Price not found';
}
})
.catch(error => {
tooltip.textContent = 'Error loading price';
console.error('Error loading price:', error);
});
}, 300); // Reduced delay for faster response
}
}, 200); // Debounce mouseover to limit request frequency
document.addEventListener('mouseover', handleMouseover);
document.addEventListener('mouseout', function(e) {
if (e.target.closest('a[href*="/dp/"], a[href*="/product/"]')) {
clearTimeout(tooltipTimeout);
tooltipTimeout = setTimeout(() => {
tooltip.style.display = 'none';
}, 100);
}
});
document.addEventListener('mousemove', updateTooltipPosition);
function updateTooltipPosition(e) {
const x = e.clientX + 10;
const y = e.clientY + 10;
tooltip.style.left = x + 'px';
tooltip.style.top = y + 'px';
}
})();