您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Quickly download images by hovering over them and pressing the S key.
// ==UserScript== // @name ImageSnatcher // @name:es ImageSnatcher // @version 1.2.3 // @description Quickly download images by hovering over them and pressing the S key. // @description:es Descarga imágenes rápidamente pasando el cursor sobre ellas y presionando la tecla S. // @author Adam Jensen // @match *://*/* // @grant GM_download // @license MIT // @namespace http://tampermonkey.net/ // ==/UserScript== (function () { 'use strict'; const validExtensions = /\.(jpe?g|png|gif|webp|bmp|svg|ico|tiff?|avif|jxl|heic|heif|dds|apng|pjpeg|pjpg|webm)$/i; const preprocessedImages = []; // Array to store the last 10 preprocessed images const maxHistory = 10; // Maximum number of images to keep in the history const downloadQueue = []; // Queue of images to be downloaded let isDownloading = false; // Flag to track the download state function preprocessImage(target) { if (!target) return; let imageUrl = null; let imageTitle = ''; if (target.tagName.toLowerCase() === 'img') { imageUrl = target.src; imageTitle = target.alt.trim() || ''; } else if (target.style.backgroundImage) { imageUrl = target.style.backgroundImage.replace(/url\(["']?([^"']+)["']?\)/, '$1'); const parentAnchor = target.closest('a'); if (parentAnchor && parentAnchor.href) { imageTitle = parentAnchor.href.split('/').pop().split('?')[0]; } } if (!imageTitle) { const parentAnchor = target.closest('a'); if (parentAnchor && parentAnchor.href) { imageTitle = parentAnchor.href.split('/').pop().split('?')[0]; } } if (!imageTitle) { imageTitle = imageUrl ? imageUrl.split('/').pop().split('?')[0] : 'unknown_image'; } imageTitle = imageTitle.replace(/[\/:*?"<>|]/g, '_'); // Make filename safe // Ensure the title has a valid extension if (!validExtensions.test(imageTitle)) { const extensionMatch = imageUrl ? imageUrl.match(validExtensions) : null; const extension = extensionMatch ? extensionMatch[0] : '.jpg'; // Default to .jpg imageTitle += extension; } // Check if the image is already in the history const existingImage = preprocessedImages.find(img => img.url === imageUrl); if (!existingImage) { // Add the new image to the history preprocessedImages.push({ url: imageUrl, title: imageTitle }); if (preprocessedImages.length > maxHistory) { preprocessedImages.shift(); // Remove the oldest image if history exceeds the limit } console.log(`Preprocessed image: URL=${imageUrl}, Title=${imageTitle}`); } } // Detect hovered image and preprocess it document.addEventListener('mousemove', function (event) { if (event.target.tagName.toLowerCase() === 'img' || event.target.style.backgroundImage) { preprocessImage(event.target); } }); // Change cursor to "loading" during the download function setCursorLoading(isLoading) { if (isLoading) { document.body.style.cursor = 'progress'; // Show loading cursor } else { document.body.style.cursor = ''; // Restore normal cursor } } // Start downloading the images in the queue function processDownloadQueue() { if (isDownloading || downloadQueue.length === 0) return; // Don't start a new download if one is already in progress or queue is empty const nextImage = downloadQueue.shift(); // Get the next image in the queue isDownloading = true; // Set the flag that download is in progress setCursorLoading(true); // Change cursor to "loading" GM_download({ url: nextImage.url, name: nextImage.title, onerror: function (err) { console.error('Failed to download the image:', err); isDownloading = false; // Reset the download flag setCursorLoading(false); // Restore cursor processDownloadQueue(); // Continue with the next image in the queue }, onload: function () { console.log(`Downloaded image: ${nextImage.title}`); isDownloading = false; // Reset the download flag setCursorLoading(false); // Restore cursor processDownloadQueue(); // Continue with the next image in the queue } }); } // Handle key press for adding the most recent preprocessed image to the download queue document.addEventListener('keydown', function (event) { // Ignore the keypress if the target is an input or textarea const activeElement = document.activeElement; const isInputField = activeElement.tagName.toLowerCase() === 'input' || activeElement.tagName.toLowerCase() === 'textarea' || activeElement.isContentEditable; if (isInputField || isDownloading) return; // Prevent adding to queue if already downloading if (event.key.toLowerCase() === 's' && preprocessedImages.length > 0) { const latestImage = preprocessedImages[preprocessedImages.length - 1]; downloadQueue.push(latestImage); // Add the image to the queue console.log(`Added image to queue: ${latestImage.title}`); processDownloadQueue(); // Start processing the queue if not already in progress } }); })();