// ==UserScript== // @name 森空岛图片下载器 // @description 给文章详情页添加一个批量下载附件图片的按钮 // @author 小旦 // @version 1.0.2 // @match *://*.skland.com/article?id=* // @grant GM_download // @run-at document-end // @require https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js // @supportURL https://greasyfork.org/zh-CN/scripts/506756-%E6%A3%AE%E7%A9%BA%E5%B2%9B%E5%9B%BE%E7%89%87%E4%B8%8B%E8%BD%BD%E5%99%A8/feedback // @license MIT // @namespace https://greasyfork.org/zh-CN/users/1002415-%E5%B0%8F%E6%97%A6 // @downloadURL none // ==/UserScript== (function() { 'use strict'; const createDownloadButton = () => { const downloadButton = document.createElement('button'); downloadButton.textContent = '下载原图'; downloadButton.style.position = 'relative'; downloadButton.style.padding = '9px'; downloadButton.style.display = 'inline-block'; downloadButton.style.backgroundColor = 'rgb(55, 55, 55)'; downloadButton.style.border = '5px solid rgb(200, 235, 33)'; downloadButton.style.borderRadius = '37px'; downloadButton.style.marginTop = '-2px'; downloadButton.style.color = 'rgb(255, 255, 255)'; downloadButton.style.fontSize = '12px'; downloadButton.style.lineHeight = '16px'; downloadButton.style.fontWeight = '700'; downloadButton.style.fontFamily = 'akrobat, Arial, sans-serif'; downloadButton.style.cursor = 'pointer'; downloadButton.addEventListener('click', function() { downloadImages(); }); return downloadButton; }; const addTargetButton = (targetDiv) => { if (!targetDiv) return; const button = createDownloadButton(); targetDiv.appendChild(button); }; const getTargetElement = () => { const relationGroupClassNamePattern = /RelationGroup__Wrapper-sc-\w+-\d+/; const elements = document.querySelectorAll('*'); for (let element of elements) { if (element.classList && element.classList.value.match(relationGroupClassNamePattern)) { return element; } } return null; }; function downloadImages() { const containers = document.querySelectorAll('.swiper-item'); if (!containers.length) { const imgs = document.querySelectorAll('img[src^="https://bbs.hycdn.cn/image/"][src$=".webp"]'); if (!imgs.length) { console.error('未找到包含指定来源的 webp 图片'); return; } const now = new Date(); const timestamp = now.toISOString().slice(0, 19).replace(/[-:T]/g, ''); let count = 1; imgs.forEach(img => { handleImageDownload(img, timestamp, count++); }); } else { const now = new Date(); const timestamp = now.toISOString().slice(0, 19).replace(/[-:T]/g, ''); let count = 1; containers.forEach((container, index) => { if (index === 0) { const firstImage = container.querySelector('img'); if (firstImage) { const images = Array.from(container.querySelectorAll('img')).slice(1); images.forEach(img => { handleImageDownload(img, timestamp, count++); }); } else { console.error('未找到首张图片'); } } else { container.querySelectorAll('img').forEach(img => { handleImageDownload(img, timestamp, count++); }); } }); } } function handleImageDownload(img, timestamp, count) { const src = img.src; const filename = `${timestamp}_${count}.webp`; console.log(`Downloading image: ${filename}`); GM_download({ url: src, name: filename, onload: function(response) { console.log(`Downloaded: ${filename}`); }, onerror: function(error) { console.error(`Failed to download: ${filename}, error: ${error}`); } }); } const delayedExecution = () => { const targetDiv = getTargetElement(); if (targetDiv) { addTargetButton(targetDiv); } else { console.log("未找到目标 div"); } }; setTimeout(delayedExecution, 3000); })();