Greasy Fork is available in English.
Bulk download Facebook album photos in full resolution, supports background downloading with minimized interruption and optimized user experience.
当前为
// ==UserScript==
// @name Facebook Photos Bulk Downloader (Background Support)
// @namespace 麦克
// @version 2.1.4
// @description Bulk download Facebook album photos in full resolution, supports background downloading with minimized interruption and optimized user experience.
// @author 麦克
// @match https://www.facebook.com/*/photos/*
// @match https://www.facebook.com/photo.php?*
// @match https://www.facebook.com/photo?*
// @match https://www.facebook.com/photo/*
// @grant GM_download
// @grant GM_notification
// @license GPL-3.0-or-later
// ==/UserScript==
let iter = 0;
let MAXITER = 10;
let isDownloading = false;
let stopDownload = false;
// 创建 Fetch 按钮并确保其持久存在
(function () {
const observer = new MutationObserver(() => {
if (document.body && !document.querySelector('#fetch-button')) {
let fetchBtn = document.createElement("div");
fetchBtn.id = "fetch-button";
fetchBtn.textContent = "⇩ Fetch Photos";
fetchBtn.style.cssText = 'position:fixed;top:10px;right:10px;z-index:9999;padding:8px;background-color:#4caf50;color:white;border-radius:5px;cursor:pointer;';
fetchBtn.onclick = startBatchDownload;
document.body.appendChild(fetchBtn);
}
});
observer.observe(document.body, { childList: true, subtree: true });
})();
// 仅在下载时防止页面关闭的提示
function handleBeforeUnload(event) {
if (isDownloading && !stopDownload) {
event.preventDefault();
event.returnValue = '正在下载照片,您确定要离开吗?';
return '正在下载照片,您确定要离开吗?';
}
}
// 获取当前图片 URL
function getImageUrl() {
const imgElement = document.querySelector('img[src*="scontent"]');
return imgElement ? imgElement.src : null;
}
// 点击“下一张”按钮
function clickNextImage() {
const nextBtn = document.querySelector('div[aria-label="下一张"], div[aria-label="Next"]');
if (nextBtn) {
nextBtn.click();
return true;
} else {
const complexNextBtn = document.querySelector('div[role="button"][tabindex="0"] div[style*="background-image"]');
if (complexNextBtn) {
complexNextBtn.click();
return true;
}
}
return false;
}
// 下载图片并确保完成后翻页
function downloadImage(imgUrl, callback) {
if (imgUrl) {
const filename = imgUrl.split('?')[0].split('/').pop();
console.log(`Downloading: ${filename}`);
GM_download({
url: imgUrl,
name: filename,
saveAs: false,
onload: callback,
onerror: callback,
});
} else {
console.error('Failed to fetch image URL.');
callback();
}
}
// 批量下载函数
function batchDownload() {
if (iter >= MAXITER || stopDownload) {
endDownload();
return;
}
const imgUrl = getImageUrl();
if (imgUrl) {
downloadImage(imgUrl, () => {
iter++;
if (clickNextImage()) {
console.log(`Moving to image ${iter + 1}`);
setTimeout(batchDownload, 1000); // 等待 1 秒后继续下载
} else {
endDownload();
}
});
} else {
console.error('Retry fetching image...');
setTimeout(() => {
if (!stopDownload) batchDownload();
}, 1000);
}
}
// 结束下载并移除事件监听器
function endDownload() {
console.log('Download completed or stopped.');
isDownloading = false;
stopDownload = true;
iter = 0;
toggleBeforeUnload(false); // 移除 beforeunload 事件
GM_notification({
text: `Download ${stopDownload ? 'stopped' : 'completed'}: ${iter} photos`,
title: 'Facebook Bulk Downloader',
timeout: 5000
});
}
// 启用或禁用 `beforeunload` 事件
function toggleBeforeUnload(enable) {
if (enable) {
window.addEventListener('beforeunload', handleBeforeUnload);
} else {
window.removeEventListener('beforeunload', handleBeforeUnload);
}
}
// 开始批量下载
function startBatchDownload() {
if (isDownloading) {
console.warn('Download already in progress.');
return;
}
iter = 0;
stopDownload = false;
MAXITER = parseInt(prompt("Enter the number of photos to download:", "10")) || 10;
console.log(`Starting download of ${MAXITER} photos...`);
isDownloading = true;
toggleBeforeUnload(true); // 启用 beforeunload 事件
GM_notification({
text: 'Download started...',
title: 'Facebook Bulk Downloader',
timeout: 3000
});
batchDownload();
}
// 用户按下 Escape 键可随时停止下载
document.addEventListener('keydown', function (e) {
if (e.key === 'Escape' && isDownloading) {
console.log('Download stopped by user.');
endDownload();
}
});