您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
支持图片预览和多图批量下载,置顶批量下载按钮
// ==UserScript== // @name 图片下载助手 // @namespace http://tampermonkey.net/ // @version alpha 1.0 // @description 支持图片预览和多图批量下载,置顶批量下载按钮 // @author Songlll // @match https://www.zqy.com/resource/* // @grant GM_download // @grant GM_xmlhttpRequest // @license MIT // @run-at document-end // ==/UserScript== (function() { 'use strict'; // 免责声明内容 const DISCLAIMER = ` <strong>免责声明:</strong> <p>本脚本仅用于个人学习研究,请尊重网站版权。下载内容仅限个人使用,禁止传播或用于商业用途。</p> <p>使用本脚本产生的任何法律责任由用户自行承担。请支持正版资源,尊重创作者劳动成果。</p> `; // 添加样式 const style = document.createElement('style'); style.innerHTML = ` /* 整体布局 */ .dh-container { position: fixed; bottom: 20px; right: 100px; z-index: 10000; display: flex; flex-direction: column; align-items: flex-end; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } /* 浮动按钮 */ .dh-toggle { width: 60px; height: 60px; border-radius: 50%; background: linear-gradient(135deg, #6a11cb 0%, #2575fc 100%); color: white; display: flex; align-items: center; justify-content: center; font-size: 24px; cursor: pointer; box-shadow: 0 6px 18px rgba(0, 0, 0, 0.2); transition: all 0.3s ease; border: none; } .dh-toggle:hover { transform: scale(1.1) rotate(90deg); box-shadow: 0 8px 25px rgba(74, 108, 247, 0.6); } /* 控制面板 */ .dh-panel { width: 360px; background: white; border-radius: 16px; box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15); overflow: hidden; margin-bottom: 15px; display: none; max-height: 80vh; } .dh-panel.active { display: block; } /* 面板头部 */ .dh-header { background: linear-gradient(135deg, #6a11cb 0%, #2575fc 100%); color: white; padding: 15px 20px; display: flex; justify-content: space-between; align-items: center; position: sticky; top: 0; z-index: 10; } .dh-title { font-size: 18px; font-weight: 600; } .dh-close { background: rgba(255, 255, 255, 0.2); border: none; width: 32px; height: 32px; border-radius: 50%; color: white; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: all 0.2s ease; font-size: 18px; } .dh-close:hover { background: rgba(255, 255, 255, 0.3); transform: rotate(90deg); } /* 面板内容 */ .dh-content { padding: 20px; max-height: calc(80vh - 150px); overflow-y: auto; } /* 免责声明 */ .dh-disclaimer { background: #fff8e1; border-left: 4px solid #ffc107; padding: 12px 15px; margin-bottom: 20px; border-radius: 4px; font-size: 13px; line-height: 1.5; } /* 统计信息 */ .dh-stats { display: flex; justify-content: space-between; margin-bottom: 15px; background: #f8fafc; padding: 15px; border-radius: 12px; } .dh-stat-item { text-align: center; } .dh-stat-value { font-size: 24px; font-weight: 700; color: #4a6cf7; line-height: 1; } .dh-stat-label { color: #64748b; font-size: 14px; } /* 操作按钮 */ .dh-action-buttons { display: grid; grid-template-columns: 1fr; gap: 12px; margin-bottom: 20px; } .dh-action-btn { padding: 14px; border-radius: 12px; border: none; font-weight: 600; cursor: pointer; display: flex; align-items: center; justify-content: center; gap: 10px; transition: all 0.2s ease; font-size: 16px; } .dh-download-all { background: linear-gradient(to right, #00c9a7, #00b09b); color: white; position: sticky; top: 60px; z-index: 5; } .dh-download-all:hover { transform: translateY(-3px); box-shadow: 0 6px 15px rgba(0, 201, 167, 0.4); } /* 单张图片下载按钮 */ .dh-single-download { background: #4A90E2; color: white; padding: 6px 12px; border-radius: 6px; border: none; cursor: pointer; display: inline-flex; align-items: center; gap: 5px; font-size: 13px; margin-left: 10px; transition: all 0.2s; } .dh-single-download:hover { background: #3a7bc8; } /* 进度条 */ .dh-progress-container { background: #f1f5f9; border-radius: 12px; overflow: hidden; margin-bottom: 15px; } .dh-progress-header { display: flex; justify-content: space-between; padding: 10px 15px; font-size: 14px; color: #64748b; } .dh-progress-bar { height: 8px; background: #e2e8f0; position: relative; } .dh-progress-fill { height: 100%; background: linear-gradient(to right, #ff9a9e, #fad0c4); width: 0%; transition: width 0.5s ease; border-radius: 0 4px 4px 0; } /* 当前文件信息 */ .dh-current-file { padding: 15px; background: #f8fafc; border-radius: 12px; font-size: 14px; margin-top: 15px; display: none; } .dh-current-file.active { display: block; } .dh-filename { font-weight: 600; color: #4a6cf7; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; margin-bottom: 5px; } /* 状态文本 */ .dh-status { font-size: 14px; color: #4a5568; text-align: center; margin: 10px 0; font-weight: 500; } /* 图片预览区域 */ .dh-preview-container { margin-top: 20px; border-top: 1px solid #eee; padding-top: 15px; } .dh-preview-title { font-weight: 600; margin-bottom: 10px; color: #4a5568; display: flex; align-items: center; justify-content: space-between; } .dh-preview-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; } .dh-preview-item { border-radius: 8px; overflow: hidden; cursor: pointer; position: relative; aspect-ratio: 4/3; background: #f5f7fa; border: 1px solid #e2e8f0; transition: all 0.2s ease; } .dh-preview-item:hover { transform: translateY(-3px); box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); border-color: #4a6cf7; } .dh-preview-item img { width: 100%; height: 100%; object-fit: cover; display: block; } .dh-preview-number { position: absolute; top: 5px; right: 5px; background: rgba(0, 0, 0, 0.6); color: white; width: 22px; height: 22px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 12px; } /* 预览弹窗 */ .dh-preview-modal { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.9); z-index: 20000; display: flex; align-items: center; justify-content: center; opacity: 0; pointer-events: none; transition: opacity 0.3s ease; } .dh-preview-modal.active { opacity: 1; pointer-events: all; } .dh-preview-content { position: relative; max-width: 90%; max-height: 90%; text-align: center; } .dh-preview-content img { max-width: 100%; max-height: 80vh; border-radius: 8px; box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3); } .dh-preview-nav { position: absolute; top: 50%; transform: translateY(-50%); width: 50px; height: 50px; background: rgba(255, 255, 255, 0.2); border-radius: 50%; display: flex; align-items: center; justify-content: center; color: white; font-size: 24px; cursor: pointer; transition: all 0.3s ease; } .dh-preview-nav:hover { background: rgba(255, 255, 255, 0.3); } .dh-preview-prev { left: 20px; } .dh-preview-next { right: 20px; } .dh-preview-close { position: absolute; top: 20px; right: 20px; background: rgba(255, 255, 255, 0.2); width: 40px; height: 40px; border-radius: 50%; display: flex; align-items: center; justify-content: center; color: white; font-size: 24px; cursor: pointer; transition: all 0.3s ease; } .dh-preview-close:hover { background: rgba(255, 255, 255, 0.3); transform: rotate(90deg); } .dh-preview-info { color: white; margin-top: 15px; font-size: 16px; } /* VIP提示 */ .vip-protection-notice { position: fixed; top: 10px; right: 10px; background-color: #4CAF50; color: white; padding: 8px 15px; border-radius: 4px; z-index: 9999; box-shadow: 0 2px 10px rgba(0,0,0,0.2); animation: fadeInOut 5s forwards; } @keyframes fadeInOut { 0% { opacity: 0; transform: translateY(-20px); } 10% { opacity: 1; transform: translateY(0); } 90% { opacity: 1; transform: translateY(0); } 100% { opacity: 0; transform: translateY(-20px); } } /* 网站原有样式覆盖 */ .cont_one { position: relative; margin-bottom: 25px; padding: 15px; background: white; border-radius: 12px; box-shadow: 0 4px 8px rgba(0,0,0,0.08); transition: transform 0.3s ease; } .cont_one:hover { transform: translateY(-5px); box-shadow: 0 6px 12px rgba(0,0,0,0.1); } .cont_one p { display: flex; align-items: center; margin-top: 10px; } .cont_one em { font-weight: bold; color: #6a11cb; } `; document.head.appendChild(style); // 创建浮动控制面板容器 const container = document.createElement('div'); container.className = 'dh-container'; document.body.appendChild(container); // 创建浮动按钮 const toggleBtn = document.createElement('button'); toggleBtn.className = 'dh-toggle'; toggleBtn.innerHTML = '⇩'; container.appendChild(toggleBtn); // 创建控制面板 const panel = document.createElement('div'); panel.className = 'dh-panel'; container.appendChild(panel); // 面板头部 const header = document.createElement('div'); header.className = 'dh-header'; header.innerHTML = ` <div class="dh-title">图片下载助手</div> <button class="dh-close">×</button> `; panel.appendChild(header); // 面板内容 const content = document.createElement('div'); content.className = 'dh-content'; content.innerHTML = ` <div class="dh-disclaimer">${DISCLAIMER}</div> <div class="dh-stats"> <div class="dh-stat-item"> <div class="dh-stat-value" id="dh-image-count">0</div> <div class="dh-stat-label">图片数量</div> </div> <div class="dh-stat-item"> <div class="dh-stat-value" id="dh-vip-status">VIP</div> <div class="dh-stat-label">账户状态</div> </div> </div> <div class="dh-action-buttons"> <button class="dh-action-btn dh-download-all" id="dh-download-all"> <svg width="16" height="16" viewBox="0 0 24 24" fill="white"> <path d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"/> </svg> 批量下载所有图片 </button> </div> <div class="dh-preview-container"> <div class="dh-preview-title"> <span>图片预览</span> <small>(点击预览大图)</small> </div> <div class="dh-preview-grid" id="dh-preview-grid"></div> </div> <div class="dh-progress-container"> <div class="dh-progress-header"> <span>下载进度</span> <span id="dh-progress-percent">0%</span> </div> <div class="dh-progress-bar"> <div class="dh-progress-fill" id="dh-progress-fill"></div> </div> </div> <div class="dh-status" id="dh-status">就绪,等待操作</div> <div class="dh-current-file" id="dh-current-file"> <div class="dh-filename" id="dh-filename">当前下载文件</div> <div id="dh-fileinfo">等待开始...</div> </div> `; panel.appendChild(content); // 创建预览弹窗 const previewModal = document.createElement('div'); previewModal.className = 'dh-preview-modal'; previewModal.innerHTML = ` <div class="dh-preview-close">×</div> <div class="dh-preview-nav dh-preview-prev">❮</div> <div class="dh-preview-content"> <img id="dh-preview-large" src="" alt="预览图"> <div class="dh-preview-info" id="dh-preview-info"></div> </div> <div class="dh-preview-nav dh-preview-next">❯</div> `; document.body.appendChild(previewModal); // 获取DOM元素 const closeBtn = header.querySelector('.dh-close'); const downloadAllBtn = document.getElementById('dh-download-all'); const progressFill = document.getElementById('dh-progress-fill'); const progressPercent = document.getElementById('dh-progress-percent'); const statusText = document.getElementById('dh-status'); const currentFile = document.getElementById('dh-current-file'); const filename = document.getElementById('dh-filename'); const fileInfo = document.getElementById('dh-fileinfo'); const imageCount = document.getElementById('dh-image-count'); const vipStatus = document.getElementById('dh-vip-status'); const previewGrid = document.getElementById('dh-preview-grid'); const previewLarge = document.getElementById('dh-preview-large'); const previewInfo = document.getElementById('dh-preview-info'); const modalClose = previewModal.querySelector('.dh-preview-close'); const modalPrev = previewModal.querySelector('.dh-preview-prev'); const modalNext = previewModal.querySelector('.dh-preview-next'); // 按钮事件 toggleBtn.addEventListener('click', () => { panel.classList.toggle('active'); }); closeBtn.addEventListener('click', () => { panel.classList.remove('active'); }); modalClose.addEventListener('click', () => { previewModal.classList.remove('active'); }); // 修复下载功能 function downloadImage(imgUrl) { // 从URL中提取文件名 const urlParts = imgUrl.split('/'); let filename = urlParts[urlParts.length - 1]; // 确保文件名有效 if (!filename || !filename.includes('.')) { filename = `image_${Date.now()}.jpg`; } // 使用GM_download API确保下载行为 if (typeof GM_download !== 'undefined') { GM_download({ url: imgUrl, name: filename, onload: function() { console.log('图片下载成功:', filename); }, onerror: function(e) { console.error('下载失败:', e); fallbackDownload(imgUrl, filename); } }); } else { // 回退方案 fallbackDownload(imgUrl, filename); } return filename; } // 回退下载方法 function fallbackDownload(imgUrl, filename) { // 创建隐藏的下载链接 const a = document.createElement('a'); a.href = imgUrl; a.download = filename; a.style.display = 'none'; document.body.appendChild(a); a.click(); document.body.removeChild(a); } // 更新进度条 function updateProgress(current, total) { const percent = Math.round((current / total) * 100); progressFill.style.width = `${percent}%`; progressPercent.textContent = `${percent}%`; statusText.textContent = `下载中: ${current}/${total}`; imageCount.textContent = total; } // 批量下载所有图片 downloadAllBtn.addEventListener('click', function() { const images = document.querySelectorAll('.cont_one img.image_1'); const total = images.length; if (total === 0) { statusText.textContent = "未找到图片!"; return; } // 禁用按钮 downloadAllBtn.disabled = true; downloadAllBtn.innerHTML = ` <svg width="16" height="16" viewBox="0 0 24 24" fill="white"> <path d="M12 4V1L8 5l4 4V6c3.31 0 6 2.69 6 6 0 1.01-.25 1.97-.7 2.8l1.46 1.46A7.93 7.93 0 0020 12c0-4.42-3.58-8-8-8zm0 14c-3.31 0-6-2.69-6-6 0-1.01.25-1.97.7-2.8L5.24 7.74A7.93 7.93 0 004 12c0 4.42 3.58 8 8 8v3l4-4-4-4v3z"/> </svg> 下载中... `; currentFile.classList.add('active'); let downloaded = 0; const downloadNext = () => { if (downloaded >= total) { statusText.textContent = "下载完成!"; downloadAllBtn.disabled = false; downloadAllBtn.innerHTML = ` <svg width="16" height="16" viewBox="0 0 24 24" fill="white"> <path d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"/> </svg> 批量下载所有图片 `; currentFile.classList.remove('active'); return; } const img = images[downloaded]; const imgUrl = img.src; // 显示当前下载文件信息 filename.textContent = `文件 ${downloaded + 1}/${total}`; fileInfo.textContent = `正在下载: ${imgUrl.split('/').pop().substring(0, 20)}...`; // 下载图片 const filenameDownloaded = downloadImage(imgUrl); downloaded++; updateProgress(downloaded, total); // 间隔1.5秒下载下一张(避免浏览器限制) setTimeout(downloadNext, 1500); }; downloadNext(); }); // 图片预览功能 function createPreviewItems() { previewGrid.innerHTML = ''; const images = document.querySelectorAll('.cont_one img.image_1'); images.forEach((img, index) => { const previewItem = document.createElement('div'); previewItem.className = 'dh-preview-item'; previewItem.innerHTML = ` <img src="${img.src}" alt="预览图 ${index + 1}"> <div class="dh-preview-number">${index + 1}</div> `; previewItem.addEventListener('click', () => { previewLarge.src = img.src; previewInfo.textContent = `图片 ${index + 1}/${images.length} - ${img.src.split('/').pop()}`; previewModal.classList.add('active'); currentPreviewIndex = index; }); previewGrid.appendChild(previewItem); }); } // 预览导航 let currentPreviewIndex = 0; modalNext.addEventListener('click', () => { const images = document.querySelectorAll('.cont_one img.image_1'); currentPreviewIndex = (currentPreviewIndex + 1) % images.length; updatePreviewImage(); }); modalPrev.addEventListener('click', () => { const images = document.querySelectorAll('.cont_one img.image_1'); currentPreviewIndex = (currentPreviewIndex - 1 + images.length) % images.length; updatePreviewImage(); }); function updatePreviewImage() { const images = document.querySelectorAll('.cont_one img.image_1'); if (images.length > 0 && currentPreviewIndex < images.length) { const img = images[currentPreviewIndex]; previewLarge.src = img.src; previewInfo.textContent = `图片 ${currentPreviewIndex + 1}/${images.length} - ${img.src.split('/').pop()}`; } } // 为每张图片添加下载按钮 function addDownloadButtons() { const containers = document.querySelectorAll('.cont_one'); containers.forEach(container => { // 检查是否已添加过按钮 if (container.querySelector('.dh-single-download')) return; const img = container.querySelector('img.image_1'); if (!img) return; const pElement = container.querySelector('p'); if (pElement) { const downloadBtn = document.createElement('button'); downloadBtn.className = 'dh-single-download'; downloadBtn.innerHTML = ` <svg width="14" height="14" viewBox="0 0 24 24" fill="white"> <path d="M19 9h-4V3H9v6H5l7 7 7-7zM5 18v2h14v-2H5z"/> </svg> 下载 `; downloadBtn.addEventListener('click', function(e) { e.stopPropagation(); // 显示控制面板 panel.classList.add('active'); // 更新状态 statusText.textContent = "正在下载单张图片..."; currentFile.classList.add('active'); const imgUrl = img.src; const filename = downloadImage(imgUrl); filename.textContent = "单张图片下载"; fileInfo.textContent = `已下载: ${filename}`; // 2秒后恢复状态 setTimeout(() => { statusText.textContent = "单张图片下载完成"; setTimeout(() => { statusText.textContent = "就绪,等待操作"; currentFile.classList.remove('active'); }, 2000); }, 500); }); pElement.appendChild(downloadBtn); } }); // 更新图片计数 imageCount.textContent = containers.length; // 创建预览项 createPreviewItems(); // 模拟VIP状态检测 vipStatus.textContent = document.querySelector('.vip-indicator') ? 'VIP' : '普通用户'; } // 初始添加按钮 addDownloadButtons(); // 监听DOM变化(处理动态加载内容) const observer = new MutationObserver(function(mutations) { mutations.forEach(() => { addDownloadButtons(); }); }); const targetNode = document.getElementById('allList'); if (targetNode) { observer.observe(targetNode, { childList: true, subtree: true }); } // 添加VIP保护提示 const vipNotice = document.createElement('div'); vipNotice.className = 'vip-protection-notice'; vipNotice.innerHTML = 'VIP权益已受保护'; document.body.appendChild(vipNotice); // 5秒后隐藏提示 setTimeout(() => { vipNotice.style.display = 'none'; }, 5000); })(); (function() { 'use strict'; // 创建样式以修复移除工具栏后的布局 const style = document.createElement('style'); style.innerHTML = ` `; document.head.appendChild(style); // 移除悬浮工具栏 function removeSlideTool() { const slideTool = document.querySelector('.slide-tool.bg-white'); if (slideTool) { slideTool.remove(); console.log('悬浮工具栏已移除'); // 显示移除通知 showRemovalNotice(); } } // 显示移除通知 function showRemovalNotice() { const notice = document.createElement('div'); notice.innerHTML = ` `; document.body.appendChild(notice); // 5秒后移除通知 setTimeout(() => { notice.style.opacity = '0'; notice.style.transform = 'translateY(20px)'; setTimeout(() => notice.remove(), 500); }, 5000); } // 初始尝试移除 removeSlideTool(); // 设置MutationObserver监听DOM变化 const observer = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { if (mutation.addedNodes && mutation.addedNodes.length > 0) { // 检查是否有新增的悬浮工具栏 const slideTool = document.querySelector('.slide-tool.bg-white'); if (slideTool) { slideTool.remove(); console.log('动态添加的悬浮工具栏已移除'); } } }); }); // 开始观察整个文档 observer.observe(document.body, { childList: true, subtree: true }); // 10秒后停止观察 setTimeout(() => { observer.disconnect(); console.log('已停止观察DOM变化'); }, 10000); })();