Greasy Fork

Greasy Fork is available in English.

Forza图库图片批量下载

批量下载Forza玩家图库的图片

当前为 2018-12-23 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         Forza图库图片批量下载
// @namespace    https://space.bilibili.com/68391#!/
// @version      0.1
// @description  批量下载Forza玩家图库的图片
// @author       剧情帝
// @match        https://www.forzamotorsport.net/*/gallery/*
// @grant        GM_registerMenuCommand
// @grant        GM_download
// @grant		 GM_addStyle
// @grant		 GM_notification
// ==/UserScript==

(function() {
	'use strict';

	let $photoArr, $photos, $selectModeBtn, $selectAllBtn, $downloadBtn, $resetBtn;
	let selectMode = false, downloading = false;
	let total_selected = 0;
	GM_registerMenuCommand('选择并下载图片', InitSelect);

	function InitSelect(){
		$photos = $("#photos").addClass('select_mode');
		$photoArr = $(".photo", $photos);
		if($photoArr.length === 0){
			alert('请在图片列表加载完毕后重试');
			return;
		}

		selectMode = true;

		GM_addStyle((`
			.photo .media_element {
				display: flex;
			}
			.photos.select_mode .photo .media_element a {
				/*pointer-events: none;*/
			}
			.photo .image {
				position: relative;
			}
			.photo .selectbox{
				display: none;
			}
			.photos.select_mode .photo .selectbox {
				display: flex;
				position: absolute;
				top: 0;
				left: 0;
				width: 100%;
				height: 100%;
				text-align: center;
				font-size: 20px;
				justify-content: center;
				align-items: center;
				background-color: rgba(0, 0, 0, 0.3);
				color: #fff;
			}
			.photos.select_mode .photo .selectbox:hover{
				background-color: unset;
				font-size: 0;
			}
			.photos.select_mode .photo .selectbox.selected{
				font-size: 0;
				background-color: unset;
				border: 5px solid #00a1d6;
			}
			.photos.select_mode .photo .selectbox.downloading{
				font-size: 20px;
				background-color: rgba(0, 0, 0, 0.3);
				border: 5px solid #ff0;
			}
			.photos.select_mode .photo .selectbox.downloaded{
				font-size: 20px;
				background-color: rgba(0, 0, 0, 0.3);
				border: 5px solid #0f0;
			}
			.photos.select_mode .photo .selectbox.failed{
				font-size: 20px;
				background-color: rgba(0, 0, 0, 0.3);
				border: 5px solid #f00;
			}
			.tool_box{
				position:fixed;
				right: 10px;
				top:40%;
				background-color: #cf4335;
				padding: 10px;
				border-radius: 3px;
				max-width: 100px;
			}
			.tool_box #mode, .tool_box label{
				vertical-align: middle;
			}
			.tool_box input[type="button"]{
				display: block;
				width: 70px;
				margin: 10px auto auto auto;
			}
			.tool_box p{
				width: 100%;
				text-align: center;
				margin-top: 10px;
			}
			`));

		let $toolBox = $(`<div class="tool_box">
				<input id="mode" type="checkbox" checked="checked"><label for="mode">选择模式</label>
				<input id="select_all" type="button" value="选择全部">
				<input id="download" type="button" value="下载">
				<input id="reset" type="button" value="重置" disabled="disabled">
				<p>在选择模式下,直接左键点击图片来选择,中键单击可以在新标签页查看图像</p>
			</div>
			`);
		$selectModeBtn = $("#mode", $toolBox);
		$selectAllBtn = $("#select_all", $toolBox);
		$downloadBtn = $("#download", $toolBox);
		$resetBtn = $("#reset", $toolBox);
		$("body").append($toolBox);

		$photoArr.each((index, photo)=>{
			let $photo = $(photo);
			let $select = $('<div class="selectbox">未选择</div>');
			$("a", $photo).click(()=>{
				return !selectMode; //图片选择模式下阻止点击图片的默认行为
			});
			$select.click( SelectPic);
			$('.image', $photo).append($select);
		});

		//“选择模式”按钮功能
		$selectModeBtn.change(()=>{
			selectMode = !selectMode;
			if(selectMode){
				$photos.addClass('select_mode');
				$selectAllBtn.prop('disabled', false);
				$downloadBtn.prop('disabled', false);
			}
			else{
				$photos.removeClass('select_mode');
				$selectAllBtn.prop('disabled', true);
				$downloadBtn.prop('disabled', true);
			}
		});

		//全选按钮功能
		$selectAllBtn.click(()=>{
			if($selectAllBtn.val() === '选择全部'){
				$(".selectbox", $photoArr).addClass('selected');
				total_selected = $photoArr.length;
			}
			else if($selectAllBtn.val() === '取消全选'){
				$(".selectbox", $photoArr).removeClass('selected');
				total_selected = 0;
			}
			AlterSelectAllButton();
		});

		//下载按钮功能
		$downloadBtn.click(DownloadImgs);

		//重置按钮功能
		$resetBtn.click(()=>{
			downloading = false;
			$selectModeBtn.prop('disabled', false);
			$selectAllBtn.prop('disabled', false).val('选择全部');
			$downloadBtn.prop('disabled', false);
			$resetBtn.prop('disabled', true);
			total_selected = 0;
			$(".selectbox.selected", $photos).removeClass('selected downloading downloaded failed').text('未选择');
		});
	}

	function SelectPic() {
		if(downloading)
			return;

		let $selectBox = $(this);
		// $selectBox.toggleClass('selected');
		if(!$selectBox.hasClass('selected')){
			$selectBox.addClass('selected');
			total_selected++;
		}
		else{
			$selectBox.removeClass('selected');
			total_selected--;
		}
		AlterSelectAllButton();
	}

	function AlterSelectAllButton() {
		$selectAllBtn.val( (total_selected === $photoArr.length) ? '取消全选' : '选择全部' );
	}

	function DownloadImgs() {
		if(total_selected === 0){
			alert('您没有选中任何图片!');
			return;
		}

		let choose = confirm(`注意:请不要在浏览器下载设置中选中 “下载前询问每个文件的保存位置” !!!否则会弹出多个对话框。\n\n已选中 ${total_selected} 张图片,点击“是”开始下载`);
		if(choose === false)
			return;

		$selectModeBtn.prop('disabled', true);
		$selectAllBtn.prop('disabled', true);
		$downloadBtn.prop('disabled', true);
		downloading = true;

		let index = 0;
		let $selectedBoxs = $(".selectbox.selected", $photos);
		let total_downloaded = 0, total_failed = 0;
		DownloadImg( index);

		//递归下载
		function DownloadImg( index) {
			if(index >= total_selected){
				//下载全部结束
				GM_notification( (total_downloaded === total_selected) ? '所有图片下载成功!' : `下载结束,成功下载${total_downloaded}张图片,${total_failed}张失败` );
				console.log( (total_downloaded === total_selected) ? '所有图片下载成功!' : `下载结束,成功下载${total_downloaded}张图片,${total_failed}张失败` );
				$resetBtn.prop('disabled', false);
				return;
			}

			let $selectedBox = $selectedBoxs.eq(index);
			let $img = $selectedBox.prev('img');
			let imgSrc = $img.attr('src').replace('/thumbnail', '');
			let imgName = `${$img.attr('title')} ${imgSrc.split('/').pop()}.jpg`;
			console.log(`第${index+1}张图片${imgName}开始下载`);
			$selectedBox.addClass('downloading').text('正在下载');
			GM_download({
				url: imgSrc,
				name: imgName,
				onload: () => {
					console.info(`第${index+1}张图片${imgName}下载成功`);
					$selectedBox.removeClass('downloading').addClass('downloaded').text('下载完成');
					total_downloaded++;
					setTimeout(() => {
						DownloadImg(index + 1);
					}, 3000);
				},
				onerror: () => {
					console.error(`第${index+1}张图片${imgName}下载失败`);
					$selectedBox.removeClass('downloading').addClass('failed').text('下载失败');
					total_failed++;
					setTimeout(() => {
						DownloadImg(index + 1);
					}, 3000);
				},
				ontimeout: () => {
					console.error(`第${index+1}张图片${imgName}下载超时`);
					$selectedBox.removeClass('downloading').addClass('failed').text('下载超时');
					total_failed++;
					setTimeout(() => {
						DownloadImg(index + 1);
					}, 3000);
				}
			});
		}
	}

})();