您需要先安装一个扩展,例如 篡改猴、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
- }
- });
- })();