您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
在Wallhaven缩略图上添加下载按钮和复选框,支持单张下载、逐个下载和打包下载。
当前为
// ==UserScript== // @name Wallhaven一键下载 // @version 1.3 // @description 在Wallhaven缩略图上添加下载按钮和复选框,支持单张下载、逐个下载和打包下载。 // @match *://wallhaven.cc/* // @require https://cdnjs.cloudflare.com/ajax/libs/jszip/3.7.1/jszip.min.js // @require https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js // @grant GM_addStyle // @license MIT // @author EPC_SG // @namespace 这是干啥的,不是很懂 // ==/UserScript== (function() { 'use strict'; // 注入CSS样式 GM_addStyle(` .download-btn { position: absolute; top: 5px; left: 6px; z-index: 1000; background: #4CAF50; color: white; border: none; border-radius: 5px; cursor: pointer; padding: 5px 10px; } .download-checkbox { position: absolute !important; top: 11px !important; left: 42px !important; z-index: 1000 !important; width: 15px !important; height: 15px !important; visibility: visible !important; } .control-btn { background: #4CAF50; color: white; padding: 5px 10px; border-radius: 5px; cursor: pointer; margin-left: 5px; } .thumb { position: relative !important; } `); // 获取图片URL const getImageUrl = (id, isPng) => { const format = isPng ? 'png' : 'jpg'; return `https://w.wallhaven.cc/full/${id.slice(0, 2)}/wallhaven-${id}.${format}`; }; // 添加按钮和复选框 const addButtons = (container) => { container.querySelectorAll('.thumb:not([data-processed])').forEach(thumb => { const id = thumb.dataset.wallpaperId; if (!id) return; thumb.dataset.processed = 'true'; const isPng = !!thumb.querySelector('.thumb-info .png'); const url = getImageUrl(id, isPng); // 下载按钮 const dlBtn = document.createElement('button'); dlBtn.className = 'download-btn'; dlBtn.innerHTML = '<i class="fas fa-download"></i>'; // 下载图标 dlBtn.onclick = async () => { const response = await fetch(url); const blob = await response.blob(); saveAs(blob, url.split('/').pop()); }; thumb.appendChild(dlBtn); // 复选框 const checkbox = document.createElement('input'); checkbox.type = 'checkbox'; checkbox.className = 'download-checkbox'; checkbox.value = url; checkbox.onclick = updateRatio; thumb.appendChild(checkbox); }); updateRatio(); }; // 批量下载 const batchDownload = async () => { const selected = document.querySelectorAll('.download-checkbox:checked'); if (!selected.length) return showProgress('未选中任何图片!'); for (const cb of selected) { const response = await fetch(cb.value); const blob = await response.blob(); saveAs(blob, cb.value.split('/').pop()); } }; // 打包下载 const packDownload = async () => { const selected = document.querySelectorAll('.download-checkbox:checked'); if (!selected.length) return showProgress('未选中任何图片!'); const zip = new JSZip(); for (let i = 0; i < selected.length; i++) { const url = selected[i].value; const response = await fetch(url); const blob = await response.blob(); zip.file(url.split('/').pop(), blob); showProgress(`正在下载:${Math.round((i + 1) / selected.length * 100)}% (${i + 1}/${selected.length})`); } zip.generateAsync({ type: 'blob' }, ({ percent }) => { showProgress(`正在打包:${Math.round(percent)}%`); }).then(blob => { saveAs(blob, 'images.zip'); showProgress('打包完成!'); }).catch(err => { console.error(err); showProgress('打包失败,请重试。'); }); }; // 更新选择比例 const updateRatio = () => { const all = document.querySelectorAll('.download-checkbox').length; const selected = document.querySelectorAll('.download-checkbox:checked').length; ratioDisplay.textContent = `已选择 ${selected} / ${all}`; }; // 全选/取消 const toggleAll = () => { const checkboxes = document.querySelectorAll('.download-checkbox'); const allChecked = Array.from(checkboxes).every(cb => cb.checked); checkboxes.forEach(cb => cb.checked = !allChecked); updateRatio(); }; // 显示进度 const showProgress = (text) => progressDisplay.textContent = text; // 初始化控制面板 const initControls = () => { const toolbar = document.querySelector('.expanded') || document.body; [ratioDisplay, selectAllButton, batchDownloadButton, packDownloadButton, progressDisplay] = [ document.createElement('span'), document.createElement('button'), document.createElement('button'), document.createElement('button'), document.createElement('span') ]; ratioDisplay.style.color = 'white'; selectAllButton.textContent = '全选/取消'; selectAllButton.className = 'control-btn'; selectAllButton.onclick = (e) => { e.preventDefault(); toggleAll(); }; batchDownloadButton.textContent = '逐个下载'; batchDownloadButton.className = 'control-btn'; batchDownloadButton.onclick = (e) => { e.preventDefault(); batchDownload(); }; packDownloadButton.textContent = '打包下载'; packDownloadButton.className = 'control-btn'; packDownloadButton.onclick = (e) => { e.preventDefault(); packDownload(); }; progressDisplay.style.color = 'white'; [ratioDisplay, selectAllButton, batchDownloadButton, packDownloadButton, progressDisplay] .forEach((el, i) => { el.style.marginLeft = `${5 + i * 5}px`; toolbar.appendChild(el); }); }; // 主逻辑 let ratioDisplay, selectAllButton, batchDownloadButton, packDownloadButton, progressDisplay; window.addEventListener('load', () => { initControls(); const listingPage = document.querySelector('.thumb-listing-page'); if (listingPage) addButtons(listingPage); const observer = new MutationObserver(mutations => { mutations.forEach(m => { m.addedNodes.forEach(node => { if (node.classList?.contains('thumb-listing-page')) addButtons(node); }); }); }); observer.observe(document.querySelector('.thumb-listing') || document.body, { childList: true, subtree: true }); }); })();