// ==UserScript==
// @name alt+单击图片自动下载
// @namespace https://www.techwb.cn/
// @version 1.1
// @description 在图片对象上面:1、按alt单击图片自动下载(默认转换为JPG格式);2、按ctrl+alt 单击图片会弹窗选择命名方式(刷新网页全局生效),文件名可以根据当前日期时间time、网页域名domain、网页标题title,或用户自定义进行命名。
// @author Techwb.cn
// @match *://*/*
// @grant GM_download
// @grant GM_setValue
// @grant GM_getValue
// @license MIT
// @downloadURL none
// ==/UserScript==
(function() {
'use strict';
// 用于判断当前是否点击了图片
var clickedImage = null;
// 获取命名方式
var nameOption = GM_getValue('nameOption', 'time'); //默认命名方式time(日期时间)、domain(域名)、title(网页标题)
var customName = GM_getValue('customName', '');
// 监听左键单击事件
document.addEventListener('mousedown', function(event) {
var target = event.target;
if (target.tagName === 'IMG' && event.button === 0) {
clickedImage = target;
if (event.altKey && !event.ctrlKey) {
// 如果按下 alt 键,自动下载
handleDownload();
} else if (event.altKey && event.ctrlKey) {
// 如果同时按下 alt 和 ctrl 键,弹出命名对话框,再下载
handleNaming();
}
}
});
// 下载图片并命名
function handleDownload() {
if (!clickedImage) return;
var imgSrc = clickedImage.src;
// 使用 fetch 方法获取图片数据,加上 mode: 'cors' 以允许跨域请求
fetch(imgSrc, { mode: 'cors' })
.then(function(response) {
// 将响应数据转为 Blob 对象
return response.blob();
})
.then(function(blob) {
// 创建 FileReader 对象,以读取 Blob 对象的数据
var reader = new FileReader();
reader.readAsDataURL(blob);
reader.onloadend = function() {
var base64data = reader.result;
// 创建 元素,并设置下载链接和文件名
var a = document.createElement('a');
var fileName = '';
if (nameOption === 'time') {
fileName = '图片_' + getDate() + '.jpg';
} else if (nameOption === 'domain') {
fileName = getDomain() + '.jpg';
} else if (nameOption === 'title') {
fileName = getTitle() + '.jpg';
} else {
fileName = customName + '.jpg';
}
a.download = fileName;
// 将图片转为 JPG 格式
var img = new Image();
img.src = base64data;
img.onload = function() {
var canvas = document.createElement('canvas');
canvas.width = img.width;
canvas.height = img.height;
var context = canvas.getContext('2d');
context.drawImage(img, 0, 0);
a.href = canvas.toDataURL('image/jpeg');
// 添加 元素到 DOM 中,模拟点击下载链接
document.body.appendChild(a);
a.click();
// 下载完成后移除 元素
document.body.removeChild(a);
document.body.removeChild(canvas);
};
}
});
}
// 弹出命名对话框并下载图片
function handleNaming() {
var dateTime = getDate();
var domainName = getDomain();
var titleName = getTitle();
var nameOptions = {
'time': '时间命名方式',
'domain': '域名命名方式',
'title': '标题命名方式',
'custom': '自定义命名方式'
};
var defaultName = dateTime + '' + titleName + '' + domainName + '.jpg';
var nameOption = GM_getValue('nameOption', 'time');
var customName = GM_getValue('customName', '');
var optionsHtml = '';
for (var option in nameOptions) {
optionsHtml += '';
}
var html = '' +
'' +
'';
var dialog = document.createElement('div');
dialog.innerHTML = html;
dialog.style.position = 'fixed';
dialog.style.top = '50%';
dialog.style.left = '50%';
dialog.style.transform = 'translate(-50%, -50%)';
dialog.style.backgroundColor = '#fff';
dialog.style.padding = '20px';
dialog.style.borderRadius = '5px';
dialog.style.boxShadow = '0px 0px 10px rgba(0, 0, 0, 0.5)';
dialog.style.zIndex = '9999';
document.body.appendChild(dialog);
var select = dialog.querySelector('#nameOption');
var customNameInput = dialog.querySelector('#customName');
var fileNameInput = dialog.querySelector('#fileName');
select.addEventListener('change', function() {
var option = select.value;
if (option === 'custom') {
customNameInput.style.display = 'block';
} else {
customNameInput.style.display = 'none';
}
updateFileName(option);
});
customNameInput.addEventListener('input', function() {
updateFileName('custom');
});
function updateFileName(option) {
var fileName = '';
if (option === 'time') {
fileName = '图片_'+dateTime+ '.jpg';
} else if (option === 'domain') {
fileName = domainName + '.jpg';
} else if (option === 'title') {
fileName = titleName + '.jpg';
} else {
fileName = customNameInput.value + '.jpg';
}
fileNameInput.value = fileName;
}
fileNameInput.addEventListener('input', function() {
var fileName = fileNameInput.value;
customNameInput.value = fileName.substring(0, fileName.lastIndexOf('.jpg'));
updateFileName('custom');
});
var confirmButton = document.createElement('button');
confirmButton.innerText = '确定';
confirmButton.style.marginTop = '20px';
confirmButton.style.padding = '5px 10px';
confirmButton.style.backgroundColor = '#2ecc71';
confirmButton.style.border = 'none';
confirmButton.style.color = '#fff';
confirmButton.style.borderRadius = '3px';
confirmButton.style.cursor = 'pointer';
confirmButton.addEventListener('click', function() {
var option = select.value;
if (option === 'custom') {
customName = customNameInput.value;
} else {
customName = '';
}
var fileName = fileNameInput.value;
GM_setValue('nameOption', option);
GM_setValue('customName', customName);
handleDownload();
document.body.removeChild(dialog);
});
var cancelButton = document.createElement('button');
cancelButton.innerText = '取消';
cancelButton.style.marginTop = '20px';
cancelButton.style.marginLeft = '20px';
cancelButton.style.padding = '5px 10px';
cancelButton.style.backgroundColor = '#e74c3c';
cancelButton.style.border = 'none';
cancelButton.style.color = '#fff';
cancelButton.style.borderRadius = '3px';
cancelButton.style.cursor = 'pointer';
cancelButton.addEventListener('click', function() {
document.body.removeChild(dialog);
});
dialog.appendChild(confirmButton);
dialog.appendChild(cancelButton);
updateFileName(nameOption);
select.dispatchEvent(new Event('change'));
}
// 获取当前日期时间字符串
function getDate() {
var now = new Date();
var date = now.getFullYear() + '-' + (now.getMonth() + 1).toString().padStart(2, '0') + '-' + now.getDate().toString().padStart(2, '0') + '_' + now.getHours().toString().padStart(2, '0') + now.getMinutes().toString().padStart(2, '0') + now.getSeconds().toString().padStart(2, '0');
return date;
}
// 获取当前页面域名
function getDomain() {
var url = window.location.href;
var domain = url.split('/')[2];
domain = domain.replace(/www\./, '');
return domain;
}
// 获取当前页面标题前10个字符
function getTitle() {
var title =document.title;
return title.substring(0, 10);
}
})();