// ==UserScript== // @name 图片打包下载工具 // @namespace http://tampermonkey.net/ // @description 简单纯洁的网页图片打包下载小工具、图片打包、A tool that helps you quickly capture web images and package them for download // @description:zh-CN 一个帮你快速捕获网页图片并打包下载的工具 // @author // @version v2.2.2 // @license GPLv3 // @icon https://s21.ax1x.com/2024/04/16/pFxNgjH.jpg // @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 *://*/* // @downloadURL none // ==/UserScript== let btnStyle = ` border: 1px solid #ccc; border-radius: 5px; background-color: #fff; cursor: pointer; height: 40px; width: 90px; border-radius: 6px; background: #333; justify-content: center; align-items: center; font-family: 'Damion', cursive; cursor: pointer; border: none; font-size: 14px; transition: 500ms; color: rgb(161, 161, 161); box-shadow: 0 0 5px #444, 5px 5px 15px #222, inset 5px 5px 10px #444,inset -5px -5px 10px #222; `; let divStyle = ` padding: 20px 10px 20px 20px; position: fixed; right: 0; bottom: 10px; z-index: 99999; transition: 500ms; `; var lock = true; const handleDownload = () => { let imageUrls = []; document.querySelectorAll("img").forEach((item) => { if (!item.src) return; imageUrls.push(item.src); }); const zip = new JSZip(); lock = false; Promise.all( imageUrls.map((url, index) => { return new Promise((resolve, reject) => { GM_xmlhttpRequest({ method: "GET", url: url, responseType: "blob", onload: function (response) { if (response.status === 200) { let blob = response.response; const filename = `image${index + 1}.jpg`; 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(() => { zip.generateAsync({ type: "blob" }).then((blob) => { saveAs(blob, "images.zip"); }); unlock(); }) .catch((error) => { unlock(); console.error("Error downloading images:", error); }); }; const unlock = (delay = 3000) => { setTimeout(() => { lock = true; }, delay); }; const createEle = () => { let div = document.createElement("div"); div.style.cssText = divStyle; div.setAttribute("id", "ccc_load_container"); function hoverOn() { div.style.cssText = ` ${divStyle} right: 0; `; } function hoverOff() { div.style.cssText = ` ${divStyle} right: -92px; `; } setTimeout(() => { hoverOff(); }, 1000); div.addEventListener("mouseover", hoverOn); div.addEventListener("mouseout", hoverOff); $(div).append(` `); document.body.appendChild(div); $("#ccc_load_container > button").click(() => { lock && handleDownload(); }); }; function getImageFileNameFromUrl(url) { // 匹配最后一个斜杠('/')之后的任何字符,直到遇到查询参数或文件扩展名的结束 const regex = /([^\/?#]+)(?=\.[\w]+($|[?#]))|([^\/?#]+)$/; const matches = url.match(regex); // 如果找到匹配项,则返回第一个匹配的文件名(可能包括文件扩展名) return matches ? matches[0] : null; } 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") { fetch(imageUrl) .then((response) => { if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return response.blob(); // 或者 response.arrayBuffer() }) .then((blob) => { // 创建一个Blob URL const url = window.URL.createObjectURL(blob); // 创建一个标签用于下载 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); // 清理标签 document.body.removeChild(a); }) .catch((error) => { console.error( "There has been a problem with your fetch operation:", error ); }); } const initBindEvent = () => { document.addEventListener("mousedown", function (event) { // 检查是否同时按下了Ctrl键和鼠标右键 if (event.ctrlKey && event.button === 2) { // 阻止右键点击的默认事件(打开上下文菜单) event.preventDefault(); console.log(" 打印选中 ", event); // 假设我们有一个ID为'targetElement'的元素要选中 var targetElement = event.target; if (targetElement) { // 选中元素,例如改变其背景色 // targetElement.style.boxShadow = '0 0 10px rgba(255, 0, 0, 0.7)'; let url = targetElement.getAttribute("src"); if (url.includes("data:image/")) { downloadImageData(url); console.log("ssssss "); } else { const fileName = getImageFileNameFromUrl(url); downloadImage(url, fileName); } } } }); }; // 初始加载样式 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); }; var cssContent = ` #flashing-div { opacity: 1; transition: opacity 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; transform: scale(0.9); } 25% { opacity: 1; transform: scale(1); } 50% { opacity: 0.9; transform: scale(0.9); } 75% { opacity: 1; transform: scale(1); } 100% { opacity: 0.9; transform: scale(0.9); visibility: hidden; /* 在动画结束时隐藏div */ } } /* 添加一个类来停止动画并隐藏div(如果需要的话) */ #flashing-div.stopped { animation: none; visibility: hidden; opacity: 0; transform: scale(0); transition: none; } `; const initTip = () => { loadStyle(); let tip = document.createElement("div"); tip.style.cssText = ` position: fixed; top: 5vh; 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.classList.add("stopped"); }, 2500); document.body.appendChild(tip); }; const init = () => { window.addEventListener("load", function () { if (window.self !== window.top) return; createEle(); initBindEvent(); setTimeout(() => { initTip(); }, 800); }); }; (function () { init(); })();