您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Greasy Fork is available in English.
简单纯洁的网页图片下载小工具 | 图片打包 | 可打包页面上所有图片下载 | 可单选(Ctrl+鼠标右键)下载单个图片 | { 功能: 1.打包所有下载 2.Ctrl+鼠标右键,下载单个 } | 没有什么花里胡哨的东西简单有效 | A tool that helps you quickly capture web images and package them for download
当前为
// ==UserScript== // @name 图片下载 | 页面所有图片打包下载 | 单个图片下载 | 想要哪张点哪张,简单有效 // @namespace http://tampermonkey.net/ // @description 简单纯洁的网页图片下载小工具 | 图片打包 | 可打包页面上所有图片下载 | 可单选(Ctrl+鼠标右键)下载单个图片 | { 功能: 1.打包所有下载 2.Ctrl+鼠标右键,下载单个 } | 没有什么花里胡哨的东西简单有效 | A tool that helps you quickly capture web images and package them for download // @description:zh-CN 一个帮你快速捕获网页图片并打包下载、也可单选下载的小工具🔧 // @author <[email protected]> // @version v3.4.3 // @license GPLv3 // @icon https://s21.ax1x.com/2024/05/14/pkmNM0s.png // @require https://code.jquery.com/jquery-3.6.0.min.js // @require https://cdnjs.cloudflare.com/ajax/libs/jszip/3.6.0/jszip.min.js // @require https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/2.0.5/FileSaver.min.js // @grant GM_xmlhttpRequest // @match *://*/* // ==/UserScript== var btnStyle = ` background-color: #fff; width: 90px; padding: 8px 0; border-radius: 6px; background: #333; justify-content: center; align-items: center; font-family: 'Damion', cursive; border: none; font-size: 14px; cursor: inherit; transition: 500ms; color: #eeeeee; box-shadow: 0 0 5px #444, 5px 5px 15px #222, inset 5px 5px 10px #444,inset -5px -5px 10px #222; `; var btn_text_style = ` margin: 0; padding: 0; font-size: 14px; `; var load_tip_style = ` position: fixed; width: 210px; padding: 12px; top: 20px; right: -220px; color: #333; background-color: #fff; box-shadow: rgba(0, 0, 0, 0.1) 0px 0px 10px 5px; border-radius: 5px; transition: all 0.5s ease-in-out 0s, transform 0.5s ease-in-out 0s; font-family: 'Damion', cursive; font-weight: 600; z-index: 9999; `; var cssContent = ` #ccc_load_container{ padding: 20px 10px 20px 20px; position: fixed; bottom: 10px; right: -92px; z-index: 99999; transition: all 0.5s ease-in-out; cursor: pointer; opacity: 0.3; } #ccc_load_container:hover{ right: 0; opacity: 1; } #flashing-div { opacity: 1; transition: all 0.8s ease-in-out, transform 0.8s ease-in-out; animation: flashAndScale 2.5s infinite; /* 初始状态设置为无限循环,稍后通过JavaScript控制 */ visibility: visible; /* 初始状态为可见 */ } @keyframes flashAndScale { 0% { opacity: 0.9; box-shadow: 0px 0px 8px 4px rgba(0, 0, 0, 0.5); } 25% { opacity: 1; box-shadow: none; box-shadow: 0px 0px 4px 2px rgba(0, 0, 0, 0.5); } 50% { opacity: 0.9; box-shadow: 0px 0px 8px 4px rgba(0, 0, 0, 0.5); } 75% { opacity: 1; box-shadow: none; box-shadow: 0px 0px 4px 2px rgba(0, 0, 0, 0.5); } 100% { opacity: 0.9; box-shadow: 0px 0px 8px 4px rgba(0, 0, 0, 0.5); } } /* 添加一个类来停止动画并隐藏div(如果需要的话) */ #flashing-div.stopped { animation: none; visibility: hidden; opacity: 0; transform: scale(0); transition: none; } `; // -------全局------------- var lock = true; // 防止事件重复调用 var allLoadDOM = null; // 按钮容器-打包下载所有 var LoadTipDOM = null; // 下载提示框 // -------------------- // 初始加载样式 const loadStyle = () => { // 创建一个新的style元素 var style = document.createElement("style"); // 将CSS样式内容设置为style元素的文本内容 if (style.styleSheet) { // 对于老版本的IE浏览器 style.styleSheet.cssText = cssContent; } else { // 对于其他浏览器 style.appendChild(document.createTextNode(cssContent)); } // 将style元素添加到head中 var head = document.head || document.getElementsByTagName("head")[0]; head.appendChild(style); }; /** * 传入配置信息创建元素并返回DOM对象 * @param {* * option { el:元素, text: 元素文本, className: 类名, prop:属性 } * mountE: 挂载元素 * } * @returns 创建元素 */ const myCreateEle = (option, mountE) => { let e = document.createElement(option.el || "div"); option.className && e.classList.add(option.className); for (let p in option.prop || {}) { e.setAttribute(p, option.prop[p]); } e.innerText = option.text || ""; e.style.cssText = option.style || ""; mountE && mountE.appendChild(e); return e; }; // 创建下载提示框 const createLoadTip = () => { LoadTipDOM = myCreateEle( { el: "div", style: `${load_tip_style}`, text: "稍等片刻,正在打包下载...", }, document.body ); }; // 打包下载所有图片事件 const handleDownload = () => { let imageUrls = []; document.querySelectorAll("img").forEach((item) => { let src = item?.src; if (!src) { src = item.getAttribute("srcset"); } if (!src) return; imageUrls.push({ src, imgName: getImageFileNameFromUrl(src) + getImageExtension(src), }); }); if (!imageUrls.length) return; const zip = new JSZip(); lock = false; !LoadTipDOM && createLoadTip(); LoadTipDOM.style.right = "20px"; Promise.all( imageUrls.map((item, index) => { return new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: "GET", url: item.src, responseType: "blob", onload: function (response) { if (response.status === 200) { let blob = response.response; const filename = item.imgName; zip.file(filename, blob, { binary: true }); } else { console.error("Request failed with status " + response.status); } resolve(); }, onerror: function (e) { console.error("Request failed: " + e.message); resolve(); }, }); }); }) ) .then(() => { let domain = window.location.href.replace(/^https?:\/\//i, ""); zip.generateAsync({ type: "blob" }).then((blob) => { saveAs(blob, `【${document.title}】【${domain}】.zip`); unlock(); }); }) .catch((error) => { unlock(); }); }; const unlock = (delay = 500) => { setTimeout(() => { lock = true; allLoadDOM.style.cursor = "pointer"; LoadTipDOM.style.right = "-220px"; }, delay); }; const createEle = () => { allLoadDOM = document.createElement("div"); allLoadDOM.setAttribute("id", "ccc_load_container"); if (!localStorage.getItem("IS_IMAGE_DOWNLOAD_TIP")) { allLoadDOM.style.right = "0"; allLoadDOM.style.opacity = "1"; setTimeout(() => { allLoadDOM.style = ""; }, 1500); } $(allLoadDOM).append(` <button style="${btnStyle}"><p style="${btn_text_style}">所有图片</p><p style="${btn_text_style}">打包下载</p></button> `); document.body.appendChild(allLoadDOM); $("#ccc_load_container > button").click(() => { lock && handleDownload(); allLoadDOM.style.cursor = "not-allowed"; }); }; // 获取图片名称 function getImageFileNameFromUrl(url) { // 正则表达式匹配最后一个'/'和第一个'?'之间的内容(如果存在) // 或者最后一个'/'和字符串结尾之间的内容(如果不存在查询参数) const regex = /\/([^?\/]+?)(?:\?|$|@)/; const match = url.match(regex); if (match && match[1]) { // match[1] 是文件名(不包括查询参数及其后面的部分) return match[1]; } return "default.jpg"; } // 获取图片扩展名 function getImageExtension(url) { var extension = url.match(/\.(jpg|jpeg|png|gif|bmp|webp|svg|tiff|tif)$/i); if (extension) { return extension[0]; } else { return ".jpg"; } } function downloadImageData(imgSrc, imgAlt = "default") { let a = document.createElement("a"); a.href = imgSrc; a.download = imgAlt || "image.png"; // 设置下载的图片名 a.style.display = "none"; document.body.appendChild(a); a.click(); document.body.removeChild(a); } function downloadImage(imageUrl, imageName = "image.png") { let url = imageUrl; if (url.includes("?")) { url = url.split("?")[0]; } if (url.includes("@")) { url = url.split("@")[0]; } if (url.includes("#")) { url = url.split("#")[0]; } if( !url.match(/https?:\/\//)){ url = window.location.protocol+'//'+window.location.hostname + '/' + url } GM_xmlhttpRequest({ method: "GET", url, responseType: "blob", onload: function (response) { if (response.status === 200) { let blob = response.response; // 创建一个Blob URL const url = window.URL.createObjectURL(blob); // 创建一个<a>标签用于下载 const a = document.createElement("a"); a.href = url; a.download = imageName; // 设置下载的文件名 a.style.display = "none"; // 触发点击事件 document.body.appendChild(a); a.click(); // 释放URL对象 window.URL.revokeObjectURL(url); // 清理<a>标签 document.body.removeChild(a); } else { console.error("下载图片失败,状态码为 " + response.status); } }, onerror: function (e) { console.error("请求失败: " + e.message); }, }); } const initBindEvent = () => { document.addEventListener("contextmenu", function (event) { if (event.ctrlKey) { // 取消默认行为(阻止上下文菜单出现) event.preventDefault(); } }); document.addEventListener("mousedown", function (event) { if (event.ctrlKey && event.button === 2) { event.preventDefault(); var targetElement = event.target; const getUrl = (dom) => { return dom.getAttribute("src") || dom.getAttribute("srcset") || ""; }; if (targetElement) { let url = getUrl(targetElement); let srcArr = []; if (url) { srcArr = [url]; } else { let arrDom = targetElement.querySelectorAll("img"); arrDom.forEach((item) => { srcArr.push(getUrl(item)); }); } srcArr.forEach((url) => { const fileName = getImageFileNameFromUrl(url); if (url.includes("data:image/")) { downloadImageData(url); } else { downloadImage(url, fileName); } }); } } }); }; const initTip = () => { let tip = document.createElement("div"); tip.style.cssText = ` position: fixed; top: 3vh; left: 50%; transform: translate(-50%, 0); background-color: rgba(0, 0, 0, 0.8); display: flex; justify-content: center; align-items: center; color: #ffffff; z-index: 999999; padding: 10px 20px; border-radius: 10px; text-align: center; letter-spacing: 1.5px; `; tip.innerText = "Ctrl + 🖱️鼠标右键 \n (下载选中图片~)"; tip.setAttribute("id", "flashing-div"); setTimeout(() => { tip.style.top = "-150px"; // tip.style.display = "none"; }, 3000); document.body.appendChild(tip); }; const init = () => { window.addEventListener("load", function () { if (window.self !== window.top) return; createEle(); initBindEvent(); loadStyle(); setTimeout(() => { if (!localStorage.getItem("IS_IMAGE_DOWNLOAD_TIP")) { localStorage.setItem("IS_IMAGE_DOWNLOAD_TIP", "1"); initTip(); } }, 200); }); }; (function () { init(); })();