站酷网下载按钮

提供站酷网原图下载功能

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==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
// ==/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 = `<svg viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg"><path d="M229.4 452.7l258.5 195.1a39.9 39.9 0 0 0 48.2 0l258.5-195.1c12.2-9.2 5.7-28.7-9.6-28.7H612.9V168a40 40 0 0 0-40-40H451.1a40 40 0 0 0-40 40v256H239c-15.3 0-21.8 19.5-9.6 28.7zM856 656H619.6a4.4 4.4 0 0 0-2.5.8l-47.3 35.7a95.8 95.8 0 0 1-115.6 0l-47.3-35.7a4.4 4.4 0 0 0-2.5-.8H168a40 40 0 0 0-40 40v160a40 40 0 0 0 40 40h688a40 40 0 0 0 40-40V696a40 40 0 0 0-40-40zM688 808a32 32 0 1 1 32-32 32 32 0 0 1-32 32zm120 0a32 32 0 1 1 32-32 32 32 0 0 1-32 32z"/></svg>`
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 = `
                <div id="${namespace("toast")}" class="${namespace("toast")}">
                </div>
            `;
            $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 = `<div id="${_id}" class="${namespace(cls)}">${text}</div>`
    $(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(`
            <div id="${id}" class="${namespace("toast__item")}">
                ${text}
            </div>
        `),
    };
    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 = `
          <style>
            .imageCollectIcons{
                width:auto !important;
            }
            .${namespace('toast')}{
                position: fixed;
                top: 50px;
                left: 50%;
                transform: translateX(-50%);
                display: flex;
                flex-direction: column;
                align-items: center;
                z-index: 99999999;
            }
            .${namespace('toast__item')}{
                padding: 10px 20px;
                background: rgba(0,0,0,0.5);
                color: #fff;
                border-radius: 5px;
                margin-bottom: 10px;
            }
            .${namespace('btns-item')} {
                margin-left: 4px;
                padding: 0 10px;
                line-height: 36px;
                font-size: 14px;
                height: 36px;
                border-radius: 4px;
                background-color: rgba(0, 0, 0, 0.6);
                display: flex;
                align-items: center;
                color: #fff;
            }
            .${namespace('btns-item')}:hover {
                color: rgb(255, 242, 0);
            }
            .${namespace('btns-item')} svg {
                margin-right: 4px;
                height: 20px;
                fill: #fff;
            }
            .${namespace('btns-item')}:hover svg{
                fill: rgb(255, 242, 0);
            }
            .${namespace('download-all-btns-item')} {
                width: 50px;
                height: 50px;
                display: inline-flex;
                align-items: center;
                justify-content: center;
                border-radius: 50%;
                box-sizing: border-box;
                position: relative;
                cursor: pointer;
                margin-top: 16px;
                border: 1px solid rgb(237, 237, 237);
                background-color: rgba(255, 255, 255, 0.9);
            }
            .${namespace('download-all-btns-item')} svg{
                height: 24px;
            }
          </style>
      `
    $('head').append(styles)
}