// ==UserScript== // @name 站酷网下载按钮 // @namespace zhanku-download // @version 1.0.2 // @icon https://static.zcool.cn/git_z/z/site/favicon.ico?version=1618914637608 // @description 提供站酷网原图下载功能 // @author sertraline // @match http*://www.zcool.com.cn/work/* // @require https://cdn.staticfile.org/jquery/3.6.2/jquery.min.js // @grant GM_openInTab // @grant GM_download // @downloadURL https://update.greasyfork.icu/scripts/388334/%E7%AB%99%E9%85%B7%E7%BD%91%E4%B8%8B%E8%BD%BD%E6%8C%89%E9%92%AE.user.js // @updateURL https://update.greasyfork.icu/scripts/388334/%E7%AB%99%E9%85%B7%E7%BD%91%E4%B8%8B%E8%BD%BD%E6%8C%89%E9%92%AE.meta.js // ==/UserScript== const IMG_SELECTOR = '.photoImage' const IMG_BOX_SELECTOR = '.photoInformationContent' const DOWNLOAD_BOX_SELECTOR = '.imageCollectIcons' const DOWNLOAD_ALL_BOX_SELECTOR = '.detailNavBox' const INDEX_MODAL_SELECTOR = '.ReactModalPortal' const NAMESPACE = GM_info.script.namespace const DOWNLOAD_ICON = `` function uuid() { return Math.random().toString(36).substr(2) } function namespace(str) { return `${NAMESPACE}-${str}` } let toasts = []; let $toastContainer; const TOAST_CONTAINER_SELECTOR = `#${namespace("toast")}`; function initToast() { if (!$toastContainer) { $toastContainer = $(TOAST_CONTAINER_SELECTOR); if (!$toastContainer.length) { const toast = `
`; $toastContainer = $(toast); $("body").append($toastContainer); } } } function createBtn({ id, text, callback, parent = "body", cls = "btns-item" }) { const _id = namespace(`${uuid()}-${id}`) if (document.getElementById(_id)) return const btn = `
${text}
` $(parent).append(btn) $(`#${_id}`).click(callback) } function openToast(text, duration = 2000) { if (!text) return; initToast(); const id = namespace(uuid + "toast") const toast = { id, element: $.parseHTML(`
${text}
`), }; toasts.push(toast); $toastContainer.append(toast.element); setTimeout(() => { $(toast.element).remove(); toasts = toasts.filter((t) => t.id !== toast.id); }, duration); } function getNameFromUrl(url) { const SPLIT_REGEXP = /\/|\?/ return new URL(url).pathname.split(SPLIT_REGEXP).pop() } function getFileTypeFromUrl(url) { const name = getNameFromUrl(url) const SPLIT_REGEXP = /\./ const res = name.split(SPLIT_REGEXP)[1] return res ? res.toUpperCase() : null } function downloadFile(url) { const name = getNameFromUrl(url) GM_download({ url, name, saveAs: true, onload: () => { openToast('下载成功') }, onerror: () => { openToast('下载失败') } }) } function main() { const sourceImgEls = document.querySelectorAll(IMG_BOX_SELECTOR) sourceImgEls.forEach(el => { const src = el.querySelector(IMG_SELECTOR).src const _src = src.split('?')[0] createBtn({ id: 'download', text: `${DOWNLOAD_ICON}下载原图`, callback() { downloadFile(_src) }, parent: el.querySelector(DOWNLOAD_BOX_SELECTOR) }) }) createBtn({ id: 'download-all', text: DOWNLOAD_ICON, callback() { const imgs = Array.from(sourceImgEls).map(el => el.querySelector(IMG_SELECTOR).src.split('?')[0]) openToast(`开始下载${imgs.length}张图片`) imgs.forEach(img => { downloadFile(img) }) }, parent: document.querySelector(DOWNLOAD_ALL_BOX_SELECTOR), cls: 'download-all-btns-item' }) } // ; (function ($) { initStyles() main() })(jQuery) function initStyles() { const styles = ` ` $('head').append(styles) }