alt+单击图片自动下载

在图片对象上面:1、按alt单击图片自动下载(默认转换为JPG格式);2、按ctrl+alt 单击图片会弹窗选择命名方式(刷新网页全局生效),文件名可以根据当前日期时间time、网页域名domain、网页标题title,或用户自定义进行命名。

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください。
// ==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
// ==/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;

        // 创建 <a> 元素,并设置下载链接和文件名
        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');
          // 添加 <a> 元素到 DOM 中,模拟点击下载链接
          document.body.appendChild(a);
          a.click();
          // 下载完成后移除 <a> 元素
          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 += '<option value="' + option + '" ' + (nameOption === option ? 'selected' : '') + '>' + nameOptions[option] + '</option>';
}
var html = '<div><label for="nameOption">命名方式:</label><select id="nameOption">' + optionsHtml + '</select></div>' +
'<div><label for="customName">自定义文件名:</label><input type="text" id="customName" value="' + customName + '"></div>' +
'<div><label for="fileName">文件名:</label><input type="text" id="fileName" value="' + defaultName + '"></div>';
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);
    }
})();