// ==UserScript==
// @name 图片下载 | 页面所有图片打包下载 | 单张下载 | 图片预览放大,旋转,信息展示 | 简单有效,想要哪张点哪张
// @namespace http://tampermonkey.net/
// @description 简单纯洁的网页图片下载工具,侵入性小不影响原网页显示,可集中展示页面所有图片,可点击预览放大,可旋转,可查看图片信息(尺寸,格式,图片大小) | (Ctrl+鼠标右键)下载单个图片
// @description:zh-CN 一个帮你快速捕获网页图片并打包下载、也可单张下载的小工具🔧
// @author <shing0727@foxmail.com>
// @version v4.1.0
// @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
// @require https://cdnjs.cloudflare.com/ajax/libs/viewerjs/1.11.6/viewer.min.js
// @grant GM_xmlhttpRequest
// @grant GM_addStyle
// @grant GM_download
// @grant GM_registerMenuCommand
// @match *://*/*
// @connect *
// @grant GM_getValue
// @grant GM_setValue
// ==/UserScript==
var isPackLoad = false
// 多图片打包下载
const downloadPackZipImgs = (all_imgs = []) => {
if (!all_imgs.length || isPackLoad) return;
isPackLoad = true
isTopLoading(true, all_imgs.length)
const zip = new JSZip();
var currNum = 0;
let total = all_imgs.length
Promise.all(
all_imgs.map((item, index) => {
if (item.blob) {
zip.file(item.imgName, item.blob, { binary: true });
realTimeSchedule(++currNum, total)
return Promise.resolve()
}
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;
item.blob = blob
if (blob.size > (1024 * 1024)) {
item.size = (blob.size / (1024 * 1024)).toFixed(1) + 'MB'
} else if (blob.size < (1024 * 1024) && blob.size > 1024) {
item.size = (blob.size / 1024).toFixed(1) + 'KB'
} else {
item.size = blob.size + '字节'
}
setItemImgsName(item)
updateNodeItem(item)
const filename = item.imgName;
zip.file(filename, blob, { binary: true });
} else {
console.error("请求报错,状态码: " + response.status);
}
realTimeSchedule(++currNum, total)
resolve();
},
onerror: function (e) {
console.error("请求失败: " + e.message);
realTimeSchedule(++currNum, total)
resolve();
},
});
});
})
)
.then(() => {
// let domain = window.location.href.replace(/^https?:\/\//i, "");
zip.generateAsync({ type: "blob" }).then((blob) => {
// saveAs(blob, `【${document.title}】【${domain}】.zip`);
let str = $('#ccc_all_page_rename_val').val()
str = str.length > 245 ? str.substring(0, 245) : str;
saveAs(blob, `${str}.zip`);
});
}).finally(() => {
isPackLoad = false
isTopLoading(false)
})
}
// 指定数组元素对象属性去重、去除宽高小于1的
function removeDuplicatesByProperty(arr = [], property) {
const seenIds = new Set();
return arr.filter(item => {
const isUnique = !seenIds.has(item[property]);
if (isUnique) {
seenIds.add(item[property]);
}
return isUnique;
});
}
// 根据blob设置图片后缀名
function setItemImgsName(item) {
try {
let { src = "", blob = {} } = item
let name = src.match(/\/([^\/?#]+)(?:[?#]|$)/)[1].split('.')[0]
if (blob?.type && blob?.type.includes('image')) {
item.lastName = blob.type.match(/^image\/([a-zA-Z0-9]+)/)[1]
item.isImg = true
} else {
item.isImg = false
}
item.imgName = decodeURIComponent(name + '.' + item.lastName)
} catch (e) {
console.log('e = ', e)
}
}
// 更新节点显示信息
function updateNodeItem(item) {
try {
$('.ccc_image_item').each(function () {
if ($(this).attr('data-imgsrc') == item.src) {
let info = ''
let imgDom = $(this).children('img')[0]
if (imgDom.naturalWidth || imgDom.naturalHeight) {
info = imgDom.naturalWidth + ' x ' + imgDom.naturalHeight
item.width = imgDom.naturalWidth
item.height = imgDom.naturalHeight
}
if (item.lastName) {
info += (' | ' + item.lastName.toUpperCase())
}
if (item.size) {
info += (' | ' + item.size)
}
$(this).find('.ccc_imgItem_info').text(info)
item.isFullInfo = true
}
})
} catch (e) {
console.log(e)
}
}
// 获取单张图片blob
const getSingleBlob = (item) => {
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;
item.blob = blob
if (blob.size > (1024 * 1024)) {
item.size = (blob.size / (1024 * 1024)).toFixed(1) + 'MB'
} else if (blob.size < (1024 * 1024) && blob.size > 1024) {
item.size = (blob.size / 1024).toFixed(1) + 'KB'
} else {
item.size = blob.size + '字节'
}
setItemImgsName(item)
updateNodeItem(item)
resolve(item);
} else {
console.error("请求报错,状态码: " + response.status);
}
},
onerror: function (e) {
console.error("请求失败: " + e.message);
reject();
},
});
})
}
// 根据svg元素返回{src,blob}
const getSvgAsFile = (svgElement) => {
// 将 SVG 元素序列化为字符串
const svgString = new XMLSerializer().serializeToString(svgElement);
// 创建一个包含 SVG 数据的 Blob 对象
const blob = new Blob([svgString], { type: 'image/svg+xml;charset=utf-8' });
// 创建一个 URL 对象
const src = URL.createObjectURL(blob);
return {
src,
blob,
}
}
// 获取页面所有图片
const loadAllImgUrls = async () => {
all_imgs = []
document.querySelectorAll("img").forEach((item) => {
let src = item?.src || item.getAttribute("srcset");
if (!src) return;
if (origin_all_imageUrls.some(n => {
if (n.src === src) {
all_imgs.push(n)
return true
} else {
false
}
})) return;
let imgName = getImageFileNameFromUrl(src)
let lastName = ''
if (imgName.includes('.')) {
let last = imgName.split('.').pop()
if (['jpg', 'jpeg', 'png', 'gif', 'bmp', 'webp', 'svg', 'tiff', 'tif', 'avif'].includes(last)) {
lastName = last
}
}
all_imgs.push({
src,
imgName,
lastName,
width: item.naturalWidth,
height: item.naturalHeight,
});
});
// 获取SVG标签图片
// document.querySelectorAll("svg").forEach((svgDom, index) => {
// let {src, blob} = getSvgAsFile(svgDom)
// const { width, height } = svgDom.getBoundingClientRect();
// all_imgs.push({
// src,
// blob,
// imgName: `svg_${index}.svg`,
// lastName: 'svg',
// width,
// height
// });
// })
resetImgsObj(all_imgs)
}
const reFetchImgs = () => {
loadAllImgUrls()
let w_min = parseInt($('#ccc_w_min').val()) || 0
let w_max = parseInt($('#ccc_w_max').val()) || 99999
let h_min = parseInt($('#ccc_h_min').val()) || 0
let h_max = parseInt($('#ccc_h_max').val()) || 99999
all_imageUrls = valid_all_imageUrls.filter(item => {
if (item.width < w_min || item.width > w_max) return false
if (item.height < h_min || item.height > h_max) return false
return true
})
reRender()
showNotify('已刷新')
}
// 显示通知
var notifyTimer = null;
function showNotify(msg) {
if (notifyTimer) {
clearTimeout(notifyTimer)
$('#ccc_notify').remove()
}
$('#ccc_popUps_container').append(`<div id="ccc_notify">${msg}</div>`)
setTimeout(() => {
$('#ccc_notify').addClass('active')
}, 16);
notifyTimer = setTimeout(() => {
$('#ccc_notify').remove()
}, 1000);
}
// 获取图片名称
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|avif)$/i);
if (extension) {
return '';
}
if (url.includes("data:image/png")) {
return '.png'
}
if (url.includes("data:image/gif")) {
return '.gif'
}
return '.jpg'
}
function deepClone(source) {
if (!source && typeof source !== 'object') {
throw new Error('error arguments', 'deepClone')
}
const targetObj = source.constructor === Array ? [] : {}
Object.keys(source).forEach(keys => {
if (source[keys] && typeof source[keys] === 'object') {
targetObj[keys] = deepClone(source[keys])
} else {
targetObj[keys] = source[keys]
}
})
return targetObj
}
var origin_all_imageUrls = []; // 所有图片
var valid_all_imageUrls = []; // 有效图片 = 所有图片 - 移除图片
var all_imageUrls = []; // 筛选后的图片
// 初始化加载图片数据
const resetImgsObj = (imgsObj = []) => {
imgsObj = removeDuplicatesByProperty(imgsObj, 'src')
if (imgsObj.length) {
origin_all_imageUrls = deepClone(imgsObj)
valid_all_imageUrls = deepClone(imgsObj)
all_imageUrls = deepClone(imgsObj)
$('.pop_title_num').text(all_imageUrls.length)
$('#load_mask').css('display', 'none')
$('#open_popUps_icon>.pop_title_num').css('display', 'block')
reRender()
} else {
}
}
// blob图片下载
const blobDownload = (item = {}) => {
let { blob, imgName } = item
// 创建一个Blob UFRL
const url = window.URL.createObjectURL(blob);
// 创建一个<a>标签用于下载
const a = document.createElement("a");
a.href = url;
a.download = imgName; // 设置下载的文件名
a.style.display = "none";
// 触发点击事件
document.body.appendChild(a);
a.click();
// 释放URL对象
window.URL.revokeObjectURL(url);
// 清理<a>标签
document.body.removeChild(a);
}
// 渲染图片列表
var viewer = null;
const reRender = () => {
// // 去除宽高小于1
// all_imageUrls = all_imageUrls.filter(item => {
// return item.width > 1 && item.height > 1
// })
$('.pop_title_num').text(all_imageUrls.length)
var $newElements = $();
all_imageUrls.forEach(item => {
let addCss = item.isFullInfo === true ? 'hide_more' : ''
var $el = $('<div>', { class: 'ccc_image_item ' + addCss, "data-imgsrc": item.src });
var $img = $('<img>', { src: item.src, alt: item.imgName, title: '预览' });
let info = '';
if (item.width || item.height) {
info = item.width + ' x ' + item.height
}
if (item.lastName) {
let s = (item.width || item.height) ? ' | ' : ''
info += (s + item.lastName.toUpperCase())
}
if (item.size) {
info += (' | ' + item.size)
}
var $infoBox = $('<div>', { text: info, class: 'ccc_imgItem_info' });
$img.appendTo($el);
$infoBox.appendTo($el);
$newElements = $.merge($newElements, $el);
});
$('#ccc_image_container').empty().append($newElements);
$('.ccc_image_item').each(function () {
$(this).append(`
<div class="ccc_imgItem_ctrl">
<div class="click_style" title="下载"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" t="1723013152119" class="icon" viewBox="0 0 1024 1024" version="1.1" p-id="6158" width="200" height="200"><path d="M862.39 161.61A222.53 222.53 0 0 0 704 96H320A224 224 0 0 0 96 320v384a224 224 0 0 0 224 224h384a224 224 0 0 0 224-224V320a222.53 222.53 0 0 0-65.61-158.39zM704 736a32 32 0 0 1-32 32H352a32 32 0 0 1-32-32 32 32 0 0 1 32-32h320a32 32 0 0 1 32 32z m-8.88-211.62L529.75 634.63a32 32 0 0 1-35.5 0L328.88 524.38A32 32 0 0 1 320 480a32 32 0 0 1 44.38-8.88l103.18 68.8a8 8 0 0 0 12.44-6.66V288a32 32 0 0 1 32-32 32 32 0 0 1 32 32v245.26a8 8 0 0 0 12.44 6.66l103.18-68.8A32 32 0 0 1 704 480a32 32 0 0 1-8.88 44.38z" fill="#ffffff" p-id="6159"/></svg></div>
</div>
<div class="ccc_imgItem_delete click_style" title="移除"><span></span></div>
`)
$(this).find('.ccc_imgItem_info').append(`
<span class="ccc_more"> ···</span>
`)
})
viewer && viewer.destroy();
viewer = new Viewer(document.getElementById('ccc_image_container'));
}
const setLoading = (target, isLoading = true) => {
if (isLoading) {
$(target).append(
`
<div id="ccc_itemImgLoading">
<div class="loader"></div>
</div>
`
)
} else {
$(target).find('#ccc_itemImgLoading').remove();
}
}
var ccc_currentVersion = 'v4.1.0';
var hasUpdate = false;
var onlineVersion = null; // 线上版本号
var online_homeUrl = 'https://greasyfork.org/zh-CN/scripts/492706-%E5%9B%BE%E7%89%87%E4%B8%8B%E8%BD%BD-%E9%A1%B5%E9%9D%A2%E6%89%80%E6%9C%89%E5%9B%BE%E7%89%87%E6%89%93%E5%8C%85%E4%B8%8B%E8%BD%BD-%E5%8D%95%E5%BC%A0%E4%B8%8B%E8%BD%BD-%E5%9B%BE%E7%89%87%E9%A2%84%E8%A7%88%E6%94%BE%E5%A4%A7-%E6%97%8B%E8%BD%AC-%E4%BF%A1%E6%81%AF%E5%B1%95%E7%A4%BA-%E7%AE%80%E5%8D%95%E6%9C%89%E6%95%88-%E6%83%B3%E8%A6%81%E5%93%AA%E5%BC%A0%E7%82%B9%E5%93%AA%E5%BC%A0'; // 脚本首页地址
var online_update_url = 'https://update.greasyfork.org/scripts/492706/%E5%9B%BE%E7%89%87%E4%B8%8B%E8%BD%BD%20%7C%20%E9%A1%B5%E9%9D%A2%E6%89%80%E6%9C%89%E5%9B%BE%E7%89%87%E6%89%93%E5%8C%85%E4%B8%8B%E8%BD%BD%20%7C%20%E5%8D%95%E5%BC%A0%E4%B8%8B%E8%BD%BD%20%7C%20%E5%9B%BE%E7%89%87%E9%A2%84%E8%A7%88%E6%94%BE%E5%A4%A7,%E6%97%8B%E8%BD%AC,%E4%BF%A1%E6%81%AF%E5%B1%95%E7%A4%BA%20%7C%20%E7%AE%80%E5%8D%95%E6%9C%89%E6%95%88%EF%BC%8C%E6%83%B3%E8%A6%81%E5%93%AA%E5%BC%A0%E7%82%B9%E5%93%AA%E5%BC%A0.user.js'; // 脚本首页地址
const loadUpdateTamp = () => {
const extractVersion = (htmlString) => {
// 使用正则表达式匹配 data-script-version 属性的值
const versionMatch = htmlString.match(/data-script-version="([^"]+)"/);
// 如果匹配成功,返回版本号;否则返回 null
return versionMatch ? versionMatch[1] : null;
}
const isUpdateAvailable = (ccc_currentVersion, onlineVersion) => {
const current = ccc_currentVersion.replace('v', '').split('.').map(Number);
const online = onlineVersion.replace('v', '').split('.').map(Number);
for (let i = 0; i < Math.max(current.length, online.length); i++) {
const currentPart = current[i] || 0; // 如果当前版本号部分不存在,则默认为 0
const onlinePart = online[i] || 0; // 如果线上版本号部分不存在,则默认为 0
if (onlinePart > currentPart) {
return true; // 如果线上版本号更高,则需要更新
} else if (onlinePart < currentPart) {
return false; // 如果线上版本号更低,则不需要更新
}
// 如果当前部分的版本号相等,继续比较下一部分
}
// 如果所有部分的版本号都相等,则不需要更新
return false;
}
GM_xmlhttpRequest({
method: "GET",
url: online_homeUrl,
onload: function (res) {
if (res.status === 200) {
onlineVersion = extractVersion(res.response)
hasUpdate = isUpdateAvailable(ccc_currentVersion, onlineVersion)
if (hasUpdate) {
GM_registerMenuCommand("有新版本啦~(♥ω", function () {
window.open(online_update_url, '_blank');
});
$('#ccc_gotoUpdate').append(`
<a href="${online_update_url}" target="_blank">有新版本啦,快去体验下吧~(♥ω</a>
`)
}
}
},
onerror: function (e) {
console.error(e);
},
});
}
// 渲染展示筛选条件
function renderViewFilter() {
let w_min = $('#ccc_w_min').val()
let w_max = $('#ccc_w_max').val() || '∞'
let h_min = $('#ccc_h_min').val()
let h_max = $('#ccc_h_max').val() || '∞'
let isView = false
$('#ccc_view_filter_itembox').empty();
if (w_min || $('#ccc_w_max').val()) {
$('#ccc_view_filter_itembox').append(`
<span>宽 ${w_min || 0} - ${w_max}</span>
`)
isView = true
}
if (h_min || $('#ccc_h_max').val()) {
$('#ccc_view_filter_itembox').append(`
<span>高 ${h_min || 0} - ${h_max}</span>
`)
isView = true
}
if (isView) {
$('.ccc_view_filter').css({ display: 'flex' })
} else {
$('.ccc_view_filter').css({ display: 'none' })
}
}
// 主要交互操作逻辑
const loadMainOperations = () => {
GM_registerMenuCommand("打开图片列表(ALT + Q)", function () {
handleOpenPopPus()
});
var isOpenPop = false;
// 处理打开弹窗
const handleOpenPopPus = () => {
isOpenPop = true;
document.querySelector('#ccc_popUps_out').style.display = 'block';
setLayout();
}
// 处理关闭弹窗
const handleClosePop = () => {
isOpenPop = false
document.querySelector('#ccc_popUps_out').style.display = 'none';
}
// 关闭弹窗
document.querySelector('#ccc_close_popUps').onclick = function () {
handleClosePop()
}
// 快捷键事件
document.addEventListener('keydown', function (event) {
// 按alt + ` 显隐弹窗
if (event.altKey && (event.key === 'Q' || event.key === 'q')) {
isOpenPop ? handleClosePop() : handleOpenPopPus()
}
// Esc键-关闭弹窗
if (event.key === 'Escape' || event.key === 'Esc') {
handleClosePop()
}
});
const setLayout = () => {
reRender() //渲染图片
let container_h = ccc_popUps_container.offsetHeight - 30;
ccc_image_container.style.height = (container_h - ccc_popUps_top.offsetHeight - 30) + 'px';
}
var isShowFilter = false;
// 显示筛选
const showHideFilter = (is, key) => {
isShowFilter = is
let speed = 300
key === 'leave' && (speed = 500)
if (key === 'enter') {
$('#ccc_filter_container').stop();
$('#ccc_filter_container').css('opacity', 1)
return;
}
if (isShowFilter) {
$('#ccc_filter_container').fadeIn(speed);
} else {
$('#ccc_filter_container').fadeOut(speed);
}
}
$('#ccc_filter_btn').click(function (e) {
e.stopPropagation(); // 阻止事件冒泡
isShowFilter = !isShowFilter
showHideFilter(isShowFilter)
})
$('#ccc_filter_container').click(function (e) {
e.stopPropagation(); // 阻止事件冒泡
})
$(document).click(function (e) {
showHideFilter(false)
})
$('#ccc_filter_container').mouseleave(function () {
showHideFilter(false, 'leave')
});
$('#ccc_filter_container').mouseenter(function () {
showHideFilter(true, 'enter')
});
// 筛选input触发
$('.ccc_filter_input').on('input', function () {
let w_min = parseInt($('#ccc_w_min').val()) || 0
let w_max = parseInt($('#ccc_w_max').val()) || 99999
let h_min = parseInt($('#ccc_h_min').val()) || 0
let h_max = parseInt($('#ccc_h_max').val()) || 99999
all_imageUrls = valid_all_imageUrls.filter(item => {
if (item.width < w_min || item.width > w_max) return false
if (item.height < h_min || item.height > h_max) return false
return true
})
reRender()
renderViewFilter()
});
// 重置筛选触发
$("#refilter_btn").click(function () {
$('#ccc_w_min').val('')
$('#ccc_w_max').val('')
$('#ccc_h_min').val('')
$('#ccc_h_max').val('')
all_imageUrls = valid_all_imageUrls
reRender()
renderViewFilter()
})
// 点击按钮下载单张图片
$('#ccc_image_container').on('click', '.ccc_imgItem_ctrl svg', function () {
let url = $(this).closest('.ccc_image_item').attr('data-imgsrc')
let item = all_imageUrls.filter(item => item.src === url)[0]
if (item.lock) return;
item.lock = true
let target = $(this).closest('.ccc_image_item')
setLoading(target, true)
if (item.lastName && item.blob) {
blobDownload(item)
item.lock = false
setLoading(target, false)
} else {
getSingleBlob(item).then(res => {
blobDownload(res)
item.lock = false
setLoading(target, false)
})
}
})
// 移除图片
$('#ccc_image_container').on('click', '.ccc_imgItem_delete', function () {
let url = $(this).closest('.ccc_image_item').attr('data-imgsrc')
valid_all_imageUrls = valid_all_imageUrls.filter(item => item.src !== url)
all_imageUrls = all_imageUrls.filter(item => item.src !== url)
reRender()
})
// 显示更多
$('#ccc_image_container').on('click', '.ccc_imgItem_info', function () {
let url = $(this).closest('.ccc_image_item').attr('data-imgsrc')
let item = all_imageUrls.filter(item => item.src === url)[0]
if (item.lock) return;
item.lock = true
$(this).find('.ccc_more').empty().append(`<div class="loader"></div>`);
$(this).closest('.ccc_image_item').find('.ccc_imgItem_ctrl>div').css('cursor', 'no-drop').removeClass('click_style')
getSingleBlob(item).then(res => {
}).finally(() => {
$(this).find('.ccc_more').remove();
$(this).css('cursor', 'initial')
$(this).closest('.ccc_image_item').find('.ccc_imgItem_ctrl>div').css('cursor', 'pointer').addClass('click_style')
item.lock = false
})
})
// 显隐主体icon
var isShowMainIcon = GM_getValue('ccc_main_icon_isshow', true);
$(document).on('click', '#showhide_main_btn', function () {
isShowMainIcon = !isShowMainIcon
handleShowHide()
})
const handleShowHide = () => {
let speed = 600
$('#ccc_main_icon_container').css({
transition: `all ${speed}ms`
})
GM_setValue('ccc_main_icon_isshow', isShowMainIcon);
if (isShowMainIcon) {
$('#ccc_main_icon_container').css({
'right': '20px',
})
$('#showhide_main_btn').css({
left: 'auto',
right: '0',
opacity: '0',
}).text('»')
} else {
$('#ccc_main_icon_container').css({
'right': '-30px',
})
$('#showhide_main_btn').css({
right: 'auto',
left: '-40px',
opacity: '1',
}).text('«')
}
setTimeout(() => {
$('#ccc_main_icon_container').css({
transition: 'none'
})
}, speed);
}
handleShowHide()
$('#ccc_popUps_container').click(function (e) {
e.stopPropagation()
})
document.getElementById('ccc_popUps_out').addEventListener("mousedown", function (event) {
if (event.target.id === 'ccc_popUps_out') {
let flag = document.querySelector('.ccc_all_pack_down_container').classList.contains('ccc_focus_rename');
if (flag) return;
handleClosePop()
}
});
// 声明拖动事件
function bindHandleDrag() {
let isMove = false
let mouseToEleY;
let mainContainerDom = document.querySelector('#ccc_main_icon_container')
let iconDom = document.querySelector('#open_popUps_icon')
let isOpen = true;
// 拖动处理
mainContainerDom.addEventListener("mousedown", function (e) {
isMove = true
// 获取鼠标相对于元素的位置
mouseToEleY = e.clientY - mainContainerDom.getBoundingClientRect().top;
});
// 当鼠标移动时
window.addEventListener('mousemove', (e) => {
if (!isMove) return
document.body.style.userSelect = 'none';
iconDom.style.cursor = 'grabbing'
// 防止默认的拖动选择文本行为
e.preventDefault();
let newTop = e.clientY - mouseToEleY;
// 防止元素超出视口下方
let maxTop = window.innerHeight - mainContainerDom.offsetHeight;
if (newTop < 0) {
newTop = 0;
} else if (newTop > maxTop) {
newTop = maxTop;
}
mainContainerDom.style.top = `${newTop}px`;
mainContainerDom.style.bottom = 'auto';
isOpen = false;
})
// 当鼠标松开时
document.querySelector('#open_popUps_icon').addEventListener('mouseup', () => {
isOpen && handleOpenPopPus() // 打开弹窗
});
window.addEventListener('mouseup', () => {
isMove = false;
iconDom.style.cursor = 'pointer'
isOpen = true
document.body.style.userSelect = 'auto';
});
}
bindHandleDrag();
// 刷新抓取
document.querySelector('#ccc_fetch_btn').onclick = () => {
reFetchImgs()
}
// 检测是否移除icon
var isRemoveIcon = GM_getValue('ccc_main_icon_isRemoveIcon', true);
handleRemoveIcon(isRemoveIcon)
GM_registerMenuCommand('(显示/移除)右下角图标', function () {
isRemoveIcon = !isRemoveIcon
GM_setValue('ccc_main_icon_isRemoveIcon', isRemoveIcon);
handleRemoveIcon(isRemoveIcon)
});
// 处理是否显示右下角图片及注册油猴Menu
function handleRemoveIcon(flag){
if(flag === true){
$('#ccc_main_icon_container').show()
}else{
$('#ccc_main_icon_container').hide()
}
}
}
// 初始声明事件
const initEvents = () => {
// ctrl+右键 下载图片
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) => {
let item = {
src: url
}
getSingleBlob(item).then(res => {
blobDownload(res)
})
});
}
}
});
document.querySelector('#ccc_all_pack_down_btn').onclick = function () {
downloadPackZipImgs(all_imageUrls)
}
// 获取textarea元素
var textareaDom = document.getElementById('ccc_all_page_rename_val')
// 监听focus事件
textareaDom.addEventListener('focus', function () {
document.querySelector('.ccc_all_pack_down_container').classList.add('ccc_focus_rename');
});
// 监听blur事件
textareaDom.addEventListener('blur', function () {
setTimeout(() => {
document.querySelector('.ccc_all_pack_down_container').classList.remove('ccc_focus_rename');
}, 100);
});
var ccc_domain = window.location.href.replace(/^https?:\/\//i, "");
var ccc_zipFileName = `【${document.title}】【${ccc_domain}】`
$(textareaDom).val(ccc_zipFileName)
}
// 打包下载loading
function isTopLoading(flag, total) {
if (flag) {
if ($('#ccc_load_tip_style').length) {
$('#ccc_load_tip_style').remove();
}
$('body').append(`
<div id="ccc_load_tip_style">
<div>稍等片刻,正在打包下载...</div>
<div class="ccc_schedule_container">
<div class="ccc_schedule_bg"><div class="ccc_schedule_curr"></div></div>
<div class="ccc_schedule_text"><span id="curr_ing">0</span>/${total}</div>
</div>
</div>
`)
$('#ccc_all_pack_down_btn').css('cursor', 'no-drop').removeClass('click_style')
} else {
$('#ccc_load_tip_style').length && $('#ccc_load_tip_style').css('right', '-280px')
$('#ccc_all_pack_down_btn').css('cursor', 'pointer').addClass('click_style')
setTimeout(() => {
$('#ccc_load_tip_style').remove();
}, 800);
}
}
// 实时计算进度条
const realTimeSchedule = (curr, total) => {
try {
if ($('#curr_ing').length) {
$('#curr_ing').text(curr)
let w = ((curr / total) * 100).toFixed(1) + '%'
$('.ccc_schedule_curr').css('width', w)
}
} catch (e) {
console.log(e)
}
}
// 初始化加载页面
const init = () => {
window.addEventListener("load", function () {
if (window.self !== window.top) return;
setTimeout(() => {
loadCss()
loadElementDOM()
loadAllImgUrls();
loadMainOperations();
initEvents();
// loadUpdateTamp()
}, 300);
});
};
(function () {
init();
})();
const loadElementDOM = () => {
$("body").append(`
<!-- 主体Icom -->
<div id="ccc_main_icon_container">
<div id="showhide_main_btn" class="none_select">»</div>
<div id="open_popUps_icon" title="ALT + Q">
<span class="pop_title_num none_select">0</span>
<svg t="1719977292759" class="icon" viewBox="0 0 1248 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
p-id="9887" width="256" height="256">
<path
d="M0 159.430165V865.420028c0 65.985105 13.006679 78.509585 76.517343 78.509585h867.120413c62.977707 0 76.504653-12.029592 76.504653-78.458827v-706.040621c0-64.322788-11.991524-78.446138-76.504653-78.446138H76.504653C13.247779 80.984027 0 92.214184 0 159.430165z m900.02414 601.479609H120.638537c85.184232-127.389321 236.670806-339.721774 275.157887-339.721774 37.268895 0 163.693818 171.561272 220.796312 231.950332 0 0 73.484566-100.665353 111.984336-100.665353 39.261137 0 170.114676 207.358192 171.38362 208.398726zM671.017758 316.33513c0-53.295662 42.065504-96.439769 94.092221-96.439768s94.092222 43.144107 94.092222 96.439768-42.065504 96.439769-94.092222 96.439769-94.092222-43.144107-94.092221-96.439769zM478.39201 33.652403L329.265673 4.631647c-49.488829-9.631287-69.132087-6.167069-81.212437 29.020756z m702.792123 136.741441l-116.742877-22.714104c0 2.905882 0.076137 5.799076 0.076136 8.654201v710.050485c0 32.992552-2.131826 70.236068-27.536092 95.767228-24.706346 24.820551-60.503265 26.90162-92.099979 26.901619h-70.439099l149.824256 29.18572c61.873725 12.042282 77.405604 2.804367 89.435196-62.44475l128.379097-693.693793c11.699667-63.206117 2.537889-79.372467-60.909327-91.706606z"
p-id="9888" fill="#333333"></path>
</svg>
</div>
</div>
<!-- 弹窗 -->
<div id="ccc_popUps_out">
<div id="ccc_popUps_container">
<div id="ccc_popUps_top">
<div id="ccc_title_ctrl">
<div class="ccc_title_text">网页图片列表 (共 <span class="pop_title_num">0</span> 张)</div>
<div id="ccc_filter_out">
<svg id="ccc_filter_btn" class="click_style" t="1719976985515" class="icon"
viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6880"
width="256" height="256">
<path
d="M577.499296 1023.99875a99.999878 99.999878 0 0 1-47.999942-11.999985l-131.999839-72.999911a99.999878 99.999878 0 0 1-51.999936-87.999893V431.999473a19.999976 19.999976 0 0 0-7.99999-15.999981L32.499961 171.99979l-3.999995-3.999995C0.5 138.99983-6.499991 96.999882 9.499989 59.999927S60.499927 0 100.499878 0h821.998997c39.999951 0 75.999907 22.999972 91.999887 59.999927s8.999989 77.999905-17.999978 107.999868l-3.999995 3.999995-307.999624 246.999699a19.999976 19.999976 0 0 0-6.999991 15.99998v488.999403a99.999878 99.999878 0 0 1-99.999878 99.999878zM84.499897 111.999863l302.999631 241.999705a98.999879 98.999879 0 0 1 37.999953 77.999905v418.999488a19.999976 19.999976 0 0 0 9.999988 17.999978l131.999839 71.999912a19.999976 19.999976 0 0 0 29.999963-17.999978V434.999469a99.999878 99.999878 0 0 1 36.999955-77.999905l303.999629-244.999701a19.999976 19.999976 0 0 0-15.99998-31.999961H100.499878a19.999976 19.999976 0 0 0-15.999981 31.999961z m881.998924 28.999965z"
fill="#333333" p-id="6881"></path>
<path
d="M983.4988 520.999364H757.499076a39.999951 39.999951 0 0 1 0-79.999902h225.999724a39.999951 39.999951 0 0 1 0 79.999902zM983.4988 670.999181H757.499076a39.999951 39.999951 0 0 1 0-79.999902h225.999724a39.999951 39.999951 0 0 1 0 79.999902zM983.4988 819.998999H757.499076a39.999951 39.999951 0 0 1 0-79.999902h225.999724a39.999951 39.999951 0 0 1 0 79.999902z"
fill="#333333" p-id="6882"></path>
</svg>
<div id="ccc_filter_container">
<div>宽:<input id="ccc_w_min" class="ccc_filter_input" type="text"
placeholder="0"><span>-</span><input id="ccc_w_max" class="ccc_filter_input"
type="text" placeholder="∞">
</div>
<div>高:<input id="ccc_h_min" class="ccc_filter_input" type="text"
placeholder="0"><span>-</span><input id="ccc_h_max" class="ccc_filter_input"
type="text" placeholder="∞">
</div>
<div>
<div id="refilter_btn" class="click_style">重置</div>
</div>
</div>
</div>
<div class="ccc_view_filter">
<span style="font-weight: bold;">筛选条件:</span>
<div id="ccc_view_filter_itembox">
</div>
</div>
</div>
<div class="ccc_popUps_top_right">
<div id="ccc_gotoUpdate"></div>
<div id="ccc_fetch_pageImgs_text">
<div id="ccc_fetch_btn" class="click_style none_select">刷新抓取</div>
<div class="ccc_fetch_tips none_select">(非首屏载入网页的图片,需刷新抓取)</div>
</div>
<div class="ccc_all_pack_down_container">
<div id="ccc_all_pack_down_btn" class="none_select click_style"><span
class="pop_title_num">0</span>打包下载
</div>
<!-- 🖊✍ -->
<div id="ccc_all_page_rename"><span class="ccc_all_page_rename_icon">✍</span>
<div class="ccc_all_page_rename_out">
<div class="ccc_all_page_rename_container">
<div class="ccc_all_page_rename_container_tips_font">重命名压缩包文件名称:</div>
<textarea id="ccc_all_page_rename_val" maxlength="255"></textarea>
</div>
</div>
</div>
</div>
<div id="ccc_close_popUps" class="none_select" title="Esc">❌</div>
</div>
</div>
<div id="load_mask">图片加载中...</div>
<div id="ccc_image_container">
<!-- <div class="ccc_image_item"></div> -->
</div>
</div>
</div>
`)
}
const loadCss = () => {
GM.addStyle(
`
/*!
* Viewer.js v1.10.5
* https://fengyuanchen.github.io/viewerjs
*
* Copyright 2015-present Chen Fengyuan
* Released under the MIT license
*
* Date: 2022-04-05T08:21:00.150Z
*/
.viewer-zoom-in::before, .viewer-zoom-out::before, .viewer-one-to-one::before, .viewer-reset::before, .viewer-prev::before, .viewer-play::before, .viewer-next::before, .viewer-rotate-left::before, .viewer-rotate-right::before, .viewer-flip-horizontal::before, .viewer-flip-vertical::before, .viewer-fullscreen::before, .viewer-fullscreen-exit::before, .viewer-close::before {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAARgAAAAUCAYAAABWOyJDAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNui8sowAAAQPSURBVHic7Zs/iFxVFMa/0U2UaJGksUgnIVhYxVhpjDbZCBmLdAYECxsRFBTUamcXUiSNncgKQbSxsxH8gzAP3FU2jY0kKKJNiiiIghFlccnP4p3nPCdv3p9778vsLOcHB2bfveeb7955c3jvvNkBIMdxnD64a94GHMfZu3iBcRynN7zAOI7TG15gHCeeNUkr8zaxG2lbYDYsdgMbktBsP03jdQwljSXdtBhLOmtjowC9Mg9L+knSlcD8TNKpSA9lBpK2JF2VdDSR5n5J64m0qli399hNFMUlpshQii5jbXTbHGviB0nLNeNDSd9VO4A2UdB2fp+x0eCnaXxWXGA2X0au/3HgN9P4LFCjIANOJdrLr0zzZ+BEpNYDwKbpnQMeAw4m8HjQtM6Z9qa917zPQwFr3M5KgA6J5rTJCdFZJj9/lyvGhsDvwFNVuV2MhhjrK6b9bFiE+j1r87eBl4HDwCF7/U/k+ofAX5b/EXBv5JoLMuILzf3Ap6Z3EzgdqHMCuF7hcQf4HDgeoHnccncqdK/TvSDWffFXI/exICY/xZyqc6XLWF1UFZna4gJ7q8BsRvgd2/xXpo6P+D9dfT7PpECtA3cnWPM0GXGFZh/wgWltA+cDNC7X+AP4GzjZQe+k5dRxuYPeiuXU7e1qwLpDz7dFjXKRaSwuMLvAlG8zZlG+YmiK1HoFqT7wP2z+4Q45TfEGcMt01xLoNZEBTwRqD4BLpnMLeC1A41UmVxsXgXeBayV/Wx20rpTyrpnWRft7p6O/FdqzGrDukPNtkaMoMo3FBdBSQMOnYBCReyf05s126fU9ytfX98+mY54Kxnp7S9K3kj6U9KYdG0h6UdLbkh7poFXMfUnSOyVvL0h6VtIXHbS6nOP+s/Zm9mvyXW1uuC9ohZ72E9uDmXWLJOB1GxsH+DxPftsB8B6wlGDN02TAkxG6+4D3TWsbeC5CS8CDFce+AW500LhhOW2020TRjK3b21HEmgti9m0RonxbdMZeVzV+/4tF3cBpP7E9mKHNL5q8h5g0eYsCMQz0epq8gQrwMXAgcs0FGXGFRcB9wCemF9PkbYqM/Bas7fxLwNeJPdTdpo4itQti8lPMqTpXuozVRVXPpbHI3KkNTB1NfkL81j2mvhDp91HgV9MKuRIqrykj3WPq4rHyL+axj8/qGPmTqi6F9YDlHOvJU6oYcTsh/TYSzWmTE6JT19CtLTJt32D6CmHe0eQn1O8z5AXgT4sx4Vcu0/EQecMydB8z0hUWkTd2t4CrwNEePqMBcAR4mrBbwyXLPWJa8zrXmmLEhNBmfpkuY2102xxrih+pb+ieAb6vGhuA97UcJ5KR8gZ77K+99xxeYBzH6Q3/Z0fHcXrDC4zjOL3hBcZxnN74F+zlvXFWXF9PAAAAAElFTkSuQmCC");
background-repeat: no-repeat;
background-size: 280px;
color: transparent;
display: block;
font-size: 0;
height: 20px;
line-height: 0;
width: 20px;
}
.viewer-zoom-in::before {
background-position: 0 0;
content: "Zoom In";
}
.viewer-zoom-out::before {
background-position: -20px 0;
content: "Zoom Out";
}
.viewer-one-to-one::before {
background-position: -40px 0;
content: "One to One";
}
.viewer-reset::before {
background-position: -60px 0;
content: "Reset";
}
.viewer-prev::before {
background-position: -80px 0;
content: "Previous";
}
.viewer-play::before {
background-position: -100px 0;
content: "Play";
}
.viewer-next::before {
background-position: -120px 0;
content: "Next";
}
.viewer-rotate-left::before {
background-position: -140px 0;
content: "Rotate Left";
}
.viewer-rotate-right::before {
background-position: -160px 0;
content: "Rotate Right";
}
.viewer-flip-horizontal::before {
background-position: -180px 0;
content: "Flip Horizontal";
}
.viewer-flip-vertical::before {
background-position: -200px 0;
content: "Flip Vertical";
}
.viewer-fullscreen::before {
background-position: -220px 0;
content: "Enter Full Screen";
}
.viewer-fullscreen-exit::before {
background-position: -240px 0;
content: "Exit Full Screen";
}
.viewer-close::before {
background-position: -260px 0;
content: "Close";
}
.viewer-container {
bottom: 0;
direction: ltr;
font-size: 0;
left: 0;
line-height: 0;
overflow: hidden;
position: absolute;
right: 0;
-webkit-tap-highlight-color: transparent;
top: 0;
-ms-touch-action: none;
touch-action: none;
-webkit-touch-callout: none;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none
}
.viewer-container::-moz-selection, .viewer-container *::-moz-selection {
background-color: transparent;
}
.viewer-container::selection,
.viewer-container *::selection {
background-color: transparent;
}
.viewer-container:focus {
outline: 0;
}
.viewer-container img {
display: block;
height: auto;
max-height: none !important;
max-width: none !important;
min-height: 0 !important;
min-width: 0 !important;
width: 100%;
}
.viewer-canvas {
bottom: 0;
left: 0;
overflow: hidden;
position: absolute;
right: 0;
top: 0
}
.viewer-canvas > img {
height: auto;
margin: 15px auto;
max-width: 90% !important;
width: auto;
}
.viewer-footer {
bottom: 0;
left: 0;
overflow: hidden;
position: absolute;
right: 0;
text-align: center;
}
.viewer-navbar {
background-color: rgba(0, 0, 0, 50%);
overflow: hidden;
}
.viewer-list {
box-sizing: content-box;
height: 50px;
margin: 0;
overflow: hidden;
padding: 1px 0
}
.viewer-list > li {
color: transparent;
cursor: pointer;
float: left;
font-size: 0;
height: 50px;
line-height: 0;
opacity: 0.5;
overflow: hidden;
transition: opacity 0.15s;
width: 30px
}
.viewer-list > li:focus,
.viewer-list > li:hover {
opacity: 0.75;
}
.viewer-list > li:focus {
outline: 0;
}
.viewer-list > li + li {
margin-left: 1px;
}
.viewer-list > .viewer-loading {
position: relative
}
.viewer-list > .viewer-loading::after {
border-width: 2px;
height: 20px;
margin-left: -10px;
margin-top: -10px;
width: 20px;
}
.viewer-list > .viewer-active,
.viewer-list > .viewer-active:focus,
.viewer-list > .viewer-active:hover {
opacity: 1;
}
.viewer-player {
background-color: #000;
bottom: 0;
cursor: none;
display: none;
left: 0;
position: absolute;
right: 0;
top: 0;
z-index: 1
}
.viewer-player > img {
left: 0;
position: absolute;
top: 0;
}
.viewer-toolbar > ul {
display: inline-block;
margin: 0 auto 5px;
overflow: hidden;
padding: 6px 3px
}
.viewer-toolbar > ul > li {
background-color: rgba(0, 0, 0, 50%);
border-radius: 50%;
cursor: pointer;
float: left;
height: 24px;
overflow: hidden;
transition: background-color 0.15s;
width: 24px
}
.viewer-toolbar > ul > li:focus,
.viewer-toolbar > ul > li:hover {
background-color: rgba(0, 0, 0, 80%);
}
.viewer-toolbar > ul > li:focus {
box-shadow: 0 0 3px #fff;
outline: 0;
position: relative;
z-index: 1;
}
.viewer-toolbar > ul > li::before {
margin: 2px;
}
.viewer-toolbar > ul > li + li {
margin-left: 1px;
}
.viewer-toolbar > ul > .viewer-small {
height: 18px;
margin-bottom: 3px;
margin-top: 3px;
width: 18px
}
.viewer-toolbar > ul > .viewer-small::before {
margin: -1px;
}
.viewer-toolbar > ul > .viewer-large {
height: 30px;
margin-bottom: -3px;
margin-top: -3px;
width: 30px
}
.viewer-toolbar > ul > .viewer-large::before {
margin: 5px;
}
.viewer-tooltip {
background-color: rgba(0, 0, 0, 80%);
border-radius: 10px;
color: #fff;
display: none;
font-size: 12px;
height: 20px;
left: 50%;
line-height: 20px;
margin-left: -25px;
margin-top: -10px;
position: absolute;
text-align: center;
top: 50%;
width: 50px;
}
.viewer-title {
color: #ccc;
display: inline-block;
font-size: 12px;
line-height: 1.2;
margin: 0 5% 5px;
max-width: 90%;
opacity: 0.8;
overflow: hidden;
text-overflow: ellipsis;
transition: opacity 0.15s;
white-space: nowrap
}
.viewer-title:hover {
opacity: 1;
}
.viewer-button {
-webkit-app-region: no-drag;
background-color: rgba(0, 0, 0, 50%);
border-radius: 50%;
cursor: pointer;
height: 80px;
overflow: hidden;
position: absolute;
right: -40px;
top: -40px;
transition: background-color 0.15s;
width: 80px
}
.viewer-button:focus,
.viewer-button:hover {
background-color: rgba(0, 0, 0, 80%);
}
.viewer-button:focus {
box-shadow: 0 0 3px #fff;
outline: 0;
}
.viewer-button::before {
bottom: 15px;
left: 15px;
position: absolute;
}
.viewer-fixed {
position: fixed;
}
.viewer-open {
overflow: hidden;
}
.viewer-show {
display: block;
}
.viewer-hide {
display: none;
}
.viewer-backdrop {
background-color: rgba(0, 0, 0, 50%);
}
.viewer-invisible {
visibility: hidden;
}
.viewer-move {
cursor: move;
cursor: -webkit-grab;
cursor: grab;
}
.viewer-fade {
opacity: 0;
}
.viewer-in {
opacity: 1;
}
.viewer-transition {
transition: all 0.3s;
}
@-webkit-keyframes viewer-spinner {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
@keyframes viewer-spinner {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.viewer-loading::after {
-webkit-animation: viewer-spinner 1s linear infinite;
animation: viewer-spinner 1s linear infinite;
border: 4px solid rgba(255, 255, 255, 10%);
border-left-color: rgba(255, 255, 255, 50%);
border-radius: 50%;
content: "";
display: inline-block;
height: 40px;
left: 50%;
margin-left: -20px;
margin-top: -20px;
position: absolute;
top: 50%;
width: 40px;
z-index: 1;
}
@media (max-width: 767px) {
.viewer-hide-xs-down {
display: none;
}
}
@media (max-width: 991px) {
.viewer-hide-sm-down {
display: none;
}
}
@media (max-width: 1199px) {
.viewer-hide-md-down {
display: none;
}
}
// -------------- my-style ------------
.viewer-backdrop {
background-color: rgba(0, 0, 0, 0.75) !important;
}
#ccc_main_icon_container {
position: fixed;
bottom: 50px;
right: 20px;
opacity: 0.3;
z-index: 88888;
display: none;
}
#open_popUps_icon {
position: relative;
width: 30px;
height: 30px;
cursor: pointer;
}
#open_popUps_icon>svg {
width: 100%;
height: 100%;
}
#open_popUps_icon>.pop_title_num {
position: absolute;
top: 0;
right: 0;
transform: translate(50%, -50%);
padding: 2px 4px;
background-color: red;
color: #ffffff;
font-size: 10px;
border-radius: 30px;
}
#showhide_main_btn {
position: absolute;
display: flex;
align-items: center;
justify-content: center;
height: 30px;
width: 20px;
font-size: 26px;
line-height: 30px;
top: 0;
right: 0;
transform: translate(100%, 0%);
cursor: pointer;
transition: all 0.3s;
font-weight: bold;
background-image: linear-gradient(to right, #ffffff, #333333);
-webkit-background-clip: text;
color: transparent;
opacity: 0;
}
#ccc_main_icon_container:hover {
opacity: 1;
}
#ccc_main_icon_container:hover #showhide_main_btn {
opacity: 1 !important;
}
#showhide_main_btn:hover {
text-shadow:
-0 -0 0 #333,
0 -0 0 #333,
-0 0 0 #333,
0 0 0 #333;
}
/* 滚动条整体样式 */
#ccc_image_container::-webkit-scrollbar {
width: 6px;
/* 宽度 */
height: 6px;
/* 高度(对于垂直滚动条) */
}
/* 滚动条滑块 */
#ccc_image_container::-webkit-scrollbar-thumb {
background: #aaa;
border-radius: 6px;
}
/* 滚动条滑块:hover状态样式 */
#ccc_image_container::-webkit-scrollbar-thumb:hover {
background: #888;
}
/* 滚动条轨道 */
#ccc_image_container::-webkit-scrollbar-track {
background: #f1f1f1;
border-radius: 6px;
}
/* 滚动条轨道:hover状态样式 */
#ccc_image_container::-webkit-scrollbar-track:hover {
background: #ddd;
}
/* 滚动条轨道:active状态样式 */
#ccc_image_container::-webkit-scrollbar-track-piece:active {
background: #eee;
}
/* 滚动条:角落样式(即两个滚动条交汇处) */
#ccc_image_container::-webkit-scrollbar-corner {
background: #535353;
}
.none_select {
user-select: none;
/* 禁止选中 */
-webkit-user-select: none;
/* 对 Safari 和旧版 Chrome 的支持 */
-moz-user-select: none;
/* 对 Firefox 的支持 */
-ms-user-select: none;
/* 对 Internet Explorer 的支持 */
}
#ccc_popUps_out {
position: fixed;
background-color: rgba(0, 0, 0, 0.6);
width: 100vw;
height: 100vh;
top: 0;
left: 0;
z-index: 88888;
display: none;
}
#ccc_popUps_container {
position: absolute;
width: 75vw;
height: 75vh;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: #ffffff;
border-radius: 8px;
box-shadow: 0px 1px 4px 0 rgba(0, 0, 0, 0.2);
padding: 15px;
}
#ccc_popUps_top {
position: relative;
display: flex;
align-items: center;
justify-content: space-between;
padding-bottom: 10px;
margin-bottom: 10px;
z-index: 10;
}
.pop_title_num {
color: red;
}
.ccc_popUps_top_right {
display: flex;
align-items: center;
justify-content: flex-end;
}
#ccc_all_pack_down_btn, #ccc_all_page_screenShot {
position: relative;
cursor: pointer;
background-color: #666666;
color: #fff;
padding: 6px 10px;
font-size: 12px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 4px;
margin-right: 30px;
transition: all 0.3s;
}
#ccc_all_page_screenShot{
margin-right: 20px;
background-color: #666666;
}
#ccc_all_page_screenShot:hover {
background-color: #333333;
box-shadow: 0 0 10px 2px rgba(0, 0, 0, 0.3);
}
#ccc_all_pack_down_btn>.pop_title_num {
/* position: absolute;
top: 0;
right: 0;
transform: translate(50%, -50%); */
padding: 2px 4px;
background-color: red;
color: #ffffff;
font-size: 10px;
line-height: 10px;
border-radius: 30px;
margin-right: 2px;
}
#ccc_close_popUps {
cursor: pointer;
filter: grayscale(100%);
font-size: 12px;
margin-left: 30px;
}
#ccc_close_popUps:hover {
filter: grayscale(0%);
}
#ccc_image_container {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
gap: 10px;
box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.1);
padding: 10px;
overflow: auto;
align-content: start;
}
.ccc_image_item {
position: relative;
height: 120px;
background-color: #f5f5f5;
display: flex;
align-items: center;
justify-content: center;
border-radius: 3px;
padding: 1px;
box-sizing: border-box;
box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.1);
}
.ccc_image_item:hover {
box-shadow: 0 0 6px 1px rgba(0, 0, 0, 0.3);
}
.ccc_image_item img {
max-width: 100%;
max-height: 100%;
object-fit: contain;
cursor: zoom-in;
}
.ccc_imgItem_info,
.ccc_imgItem_ctrl,
.ccc_imgItem_delete {
position: absolute;
background-color: rgba(0, 0, 0, 0.6);
color: #fff;
box-sizing: border-box;
font-size: 10px;
display: flex;
align-items: center;
opacity: 0;
transition: all 0.3s;
}
.ccc_imgItem_info {
left: 0;
top: 0;
padding: 3px 5px;
border-bottom-right-radius: 5px;
flex-wrap: wrap;
max-width: 80%;
line-height: 14px;
}
.ccc_imgItem_ctrl {
right: 0;
bottom: 0;
color: #fff;
padding: 3px 6px;
border-top-left-radius: 5px;
}
.ccc_imgItem_delete {
right: 0;
top: 0;
padding: 8px;
background-color: transparent;
cursor: pointer;
transition: all 0.3s;
}
.ccc_imgItem_delete>span {
width: 14px;
height: 3px;
border-radius: 6px;
background-color: rgba(255, 0, 0, 1);
}
.ccc_imgItem_ctrl>div {
width: 17px;
height: 17px;
cursor: pointer;
transition: all 0.3s;
}
.ccc_imgItem_ctrl svg {
width: 100%;
height: 100%;
}
.ccc_image_item:hover .ccc_imgItem_info,
.ccc_image_item:hover .ccc_imgItem_ctrl,
.ccc_image_item:hover .ccc_imgItem_delete {
opacity: 1;
}
.viewer-container {
z-index: 99999 !important;
}
#ccc_title_ctrl {
display: flex;
align-items: center;
}
#ccc_title_ctrl>.ccc_title_text {
font-size: 14px;
}
#ccc_filter_out {
position: relative;
top: 1px;
display: flex;
width: 18px;
height: 18px;
margin-left: 20px;
}
#ccc_filter_out svg {
width: 100%;
height: 100%;
cursor: pointer;
transition: all 0.3s;
}
.ccc_view_filter {
/* display: flex; */
align-items: center;
font-size: 12px;
/* background-color: #fafafa; */
/* padding: 10px 14px; */
border-radius: 4px;
margin-left: 14px;
display: none;
}
#ccc_view_filter_itembox {
display: flex;
flex-wrap: wrap;
align-items: center;
max-width: 400px;
}
#ccc_view_filter_itembox>span {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 3px 8px;
font-size: 11px;
border-radius: 4px;
box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.3);
background-color: #f5f5f5;
margin-left: 8px;
}
#ccc_view_filter_itembox>span:first-of-type {
margin-left: 0;
}
#ccc_filter_container {
position: absolute;
top: 50%;
left: 40px;
transform: translate(0, -50%);
padding: 10px 15px;
background: #fff;
border: 1px solid #555;
box-shadow: 0 2px 10px 0 rgba(0, 0, 0, 0.6);
border-radius: 6px;
z-index: 9;
display: none;
width: 160px;
font-size: 14px;
/* opacity: 0; */
}
#ccc_filter_container::before,
#ccc_filter_container::after {
position: absolute;
content: '';
top: 50%;
}
#ccc_filter_container::before {
left: -23px;
margin-top: -13px;
border: 13px solid transparent;
border-right: 12px solid #fff;
z-index: 2;
}
#ccc_filter_container::after {
left: -26px;
margin-top: -13px;
border: 13px solid transparent;
border-right: 13px solid #555;
z-index: 1;
}
#ccc_filter_container>div {
width: 100%;
display: flex;
align-items: center;
margin: 6px auto;
align-items: center;
justify-content: center;
}
#ccc_filter_container>div>span {
width: 10%;
text-align: center;
display: block;
}
#ccc_filter_container>div input {
width: 35%;
height: 18px;
font-size: 13px;
text-align: center;
}
#ccc_filter_container>div input::placeholder {
text-align: center;
line-height: 18px;
}
#refilter_btn {
width: 40px;
height: 20px;
font-size: 10px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 2px;
box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.2);
color: #ffffff;
background-color: #666666;
letter-spacing: 1px;
cursor: pointer;
transition: all 0.3s;
}
#refilter_btn:hover {
background-color: #333333;
box-shadow: 0 0 4px 1px rgba(0, 0, 0, 0.2);
}
#ccc_w_max::placeholder,
#ccc_h_max::placeholder {
position: relative;
top: 5px;
font-size: 26px;
}
#load_mask {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 18px;
letter-spacing: 1px;
padding: 10px 20px;
border-radius: 4px;
color: #fff;
background-color: rgba(0, 0, 0, 0.6);
z-index: 100;
}
.loader {
width: 30px;
height: 30px;
border: 3px solid #f3f3f3;
/* 边框的颜色 */
border-top: 3px solid #3498db;
/* 上边框颜色,旋转时的主要颜色 */
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
.ccc_more {
cursor: pointer;
display: inline-block;
margin-left: 4px;
}
.ccc_imgItem_info:hover .ccc_more {
color: rgb(24, 144, 255)
}
.ccc_imgItem_info:hover {
cursor: pointer;
}
.ccc_more>.loader {
width: 12px;
height: 12px;
border: 2px solid #f3f3f3;
border-top: 2px solid #3498db;
}
#ccc_load_tip_style {
position: fixed;
width: 210px;
padding: 12px 24px;
top: 20px;
right: 20px;
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;
text-align: center;
z-index: 999999;
}
#ccc_gotoUpdate {
position: relative;
margin-right: 20px;
line-height: 24px;
}
#ccc_gotoUpdate>a {
text-decoration: none;
cursor: pointer;
color: #909090;
font-size: 12px;
transition: all 0.3s ease;
}
#ccc_gotoUpdate:hover>a {
color: #007fff;
}
#ccc_gotoUpdate::before {
content: '';
position: absolute;
left: 0;
bottom: 0;
height: 1px;
width: 0;
background-color: #007fff;
transition: all 0.3s ease;
}
#ccc_gotoUpdate:hover::before {
width: 100%;
}
.ccc_schedule_container {
margin-top: 5px;
display: flex;
align-items: center;
}
.ccc_schedule_text {
text-align: center;
font-size: 14px;
white-space: nowrap;
padding-left: 10px;
}
.ccc_schedule_bg {
position: relative;
flex-grow: 1;
height: 4px;
border-radius: 2px;
background-color: #ddd;
margin: 2px auto;
overflow: hidden;
}
.ccc_schedule_curr {
height: 100%;
background-color: #67C23A;
width: 20%;
transition: all 0.3s ease;
}
#curr_ing {
color: #67C23A;
}
#ccc_fetch_pageImgs {
display: flex;
width: 20px;
height: 20px;
margin: auto 20px;
}
#ccc_fetch_pageImgs>svg {
width: 100%;
height: 100%;
}
#ccc_fetch_pageImgs_text{
position: relative;
font-size: 14px;
margin-right: 20px;
}
#ccc_fetch_btn{
cursor: pointer;
padding: 3px 0;
transition: all 0.1s ease;
}
#ccc_fetch_pageImgs_text>.ccc_fetch_tips{
position: absolute;
/* color: #F56C6C; */
color: #999999;
font-size: 11px;
top: 100%;
right: 0;
width: 0%;
text-align: right;
letter-spacing: 1px;
opacity: 0;
white-space: nowrap; /* 确保文本不会换行 */
overflow: hidden; /* 隐藏超出div的文本 */
text-overflow: ellipsis; /* 超出部分显示省略号 */
transition: all 0.4s ease;
}
#ccc_fetch_btn:hover{
color: #007fff;
}
#ccc_fetch_btn:hover + .ccc_fetch_tips{
width: 400%;
opacity: 1;
}
#ccc_fetch_btn:active{
transform: translate3d(0, 1px, 0);
}
.click_style:active {
transform: scale(0.9);
}
#ccc_notify{
position: absolute;
top: 30px;
left: 50%;
transform: translate(-50%, 0);
background-color: rgb(226, 244, 219);
color: #67C23A;
padding: 8px 20px;
border-radius: 4px;
font-size: 14px;
letter-spacing: 1px;
z-index: 8;
opacity: 0;
transition: all 0.3s ease;
}
#ccc_notify.active{
top: 70px;
opacity: 1;
}
.ccc_all_pack_down_container{
display: flex;
background-color: #666666;
border-radius: 4px;
transition: all 0.3s;
cursor: pointer;
}
.ccc_all_pack_down_container:hover {
box-shadow: 0 0 10px 2px rgba(0, 0, 0, 0.3);
}
.ccc_all_pack_down_container> #ccc_all_pack_down_btn{
margin-right: 0;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
background-color: initial;
}
.ccc_all_pack_down_container>#ccc_all_pack_down_btn:hover{
background-color: #333333;
}
#ccc_all_page_rename{
position: relative;
width: 20px;
display: flex;
align-items: center;
justify-content: center;
border-top-right-radius: 4px;
border-bottom-right-radius: 4px;
border-left: 1px solid #555;
color: #eee;
}
#ccc_all_page_rename>.ccc_all_page_rename_icon{
position: absolute;
top: 45%;
left: 50%;
transform: translate(-50%, -50%);
box-sizing: border-box;
font-size: 12px;
transition: all 0.3s;
}
.ccc_all_pack_down_container>#ccc_all_page_rename:hover .ccc_all_page_rename_icon, .ccc_focus_rename .ccc_all_page_rename_icon{
font-size: 55px !important;
z-index: 999 !important;
}
.ccc_all_pack_down_container>#ccc_all_page_rename:hover, .ccc_focus_rename #ccc_all_page_rename{
background-color: #eee;
color: red;
}
.ccc_all_page_rename_out{
/* display: none; */
visibility:hidden;
position: absolute;
top: 100%;
padding: 10px 50px 50px 50px;
cursor: initial;
}
.ccc_all_page_rename_container{
opacity: 0;
width: 0;
/* width: 340px; */
padding: 10px;
border-radius: 10px;
color: #333;
/* background-color: #f5f5f5; */
cursor: initial;
box-shadow: 0 0 10px 2px rgba(0, 0, 0, 0.3);
background-color: rgba(255, 255, 255, 0.6); /* 设置半透明背景 */
backdrop-filter: blur(10px); /* 应用背景模糊效果 */
-webkit-backdrop-filter: blur(10px); /* 兼容老版本Safari */
transition: all 0.3s;
}
.ccc_all_pack_down_container>#ccc_all_page_rename:hover .ccc_all_page_rename_out, .ccc_focus_rename .ccc_all_page_rename_out{
display: block;
visibility: visible;
}
.ccc_all_pack_down_container>#ccc_all_page_rename:hover .ccc_all_page_rename_container, .ccc_focus_rename .ccc_all_page_rename_container{
width: 340px;
opacity: 1;
}
.ccc_all_page_rename_container_tips_font{
font-size: 13px;
font-weight: 550;
letter-spacing: 0.5px;
margin-bottom: 5px;
white-space: nowrap;
}
#ccc_all_page_rename_val{
max-width: 100%;
min-width: 100%;
min-height: 100px;
box-sizing: border-box;
border: none;
outline: none; /* 可选:移除聚焦时的轮廓 */
padding: 4px 6px;
border-radius: 6px;
box-shadow: 0 0 10px 1px rgba(0, 0, 0, 0.1);
background-color: rgba(255, 255, 255, 0.7); /* 设置半透明背景 */
}
`
);
}