// ==UserScript==
// @name Facebook Cleaner & Expand post area & Hide video titles during Facebook Reels playback.
// @name:zh-TW Facebook 乾淨化 & 加寬貼文區 & 播放連續短片時隱藏影片標題
// @name:zh-CN Facebook 乾淨化 & 加宽贴文区 & 播放连续短片时隐藏影片标题
// @namespace http://tampermonkey.net/
// @version 4.6
// @description Remove unnecessary and rarely used feature buttons and elements from Facebook to make the entire page look cleaner and more streamlined, Widen the post area to improve the overall visual experience, Hide video titles during Facebook Reels playback.
// @description:zh-TW 刪除FaceBook多餘、不常使用的功能按鈕和要素,使整個頁面看起來更加簡潔,加寬貼文區,讓整體觀感更好,播放連續短片時隱藏影片標題
// @description:zh-CN 删除FaceBook多余、不常使用的功能按钮和要素,使整个页面看起来更加简洁,加宽贴文区,让整体观感更好,播放连续短片时隐藏影片标题
// @author chatgpt
// @match https://www.facebook.com/*
// @grant none
// @license MIT
// ==/UserScript==
(function () {
'use strict';
/***** === 第一階段:Facebook 清爽化(先執行)=== *****/
(function cleanerPhase() {
// 需要隱藏的左側選單文字
const leftKeywords = [
// 繁體中文
'動態回顧', '我的珍藏', '我的收藏', 'Marketplace', '兒童版 Messenger',
'玩遊戲', '近期廣告動態', '訂單和付款', '氣候科學中心', '募款活動', '籌款活動',
'廣告管理員', 'Meta Quest 3S',
// 簡體中文
'那年今天', '收藏夹', '广告管理工具', '气候科学中心',
'订单与支付', '玩游戏', '近期广告动态', '筹款活动', 'Messenger 少儿版',
// 英文
'Memories', 'Saved', 'Messenger Kids',
'Gaming', 'Play games', 'Recent ad activity', 'Orders and payments',
'Climate Science Center', 'Fundraisers', 'Ads Manager'
];
// 「顯示更多」與「顯示較少」的相關文字
const moreKeywords = ['顯示更多', '更多', '展开', 'See more', 'More', 'Show more', 'See More', 'MORE', 'SHOW MORE'];
const lessKeywords = ['顯示較少', '收起', 'Show less', 'Show Less', 'Less', 'LESS'];
// 其他要移除的元素選擇器
const selectors = [
'footer',
'div[role="contentinfo"]',
'div[aria-label="Facebook"] > div:last-child'
];
// 確認是否為有側欄的主要頁面
function isMainSidebarPage() {
return !!document.querySelector('nav[role="navigation"], [role=navigation]');
}
// 根據文字內容隱藏左側欄目
function hideLeftSidebarByText() {
document.querySelectorAll('nav a[role="link"], [role=navigation] a[role="link"]').forEach(a => {
let match = false;
a.querySelectorAll('span.x1lliihq').forEach(span => {
if (span.textContent && leftKeywords.includes(span.textContent.trim()) && span.children.length === 0) {
match = true;
}
});
if (match) a.style.display = 'none';
});
}
// 根據標題文字隱藏右側欄
function hideRightSidebarByTitle() {
const rightKeywords = ['贊助', '聯絡人', '联系人', '群組聊天室', '群聊', 'Sponsored', 'Contacts', 'Group conversations'];
document.querySelectorAll('h3').forEach(h3 => {
if (h3.textContent && rightKeywords.some(kw => h3.textContent.includes(kw))) {
let parent = h3;
for (let i = 0; i < 6; i++) if (parent.parentElement) parent = parent.parentElement;
if (parent && parent.offsetWidth > 200) parent.style.display = 'none';
}
});
}
// 隱藏左側選單中的 Marketplace 按鈕
function removeMarketplaceButton() {
document.querySelectorAll('a[aria-label="Marketplace"], a[href="/marketplace/?ref=app_tab"], a[href="/marketplace/"]').forEach(a => {
let li = a;
for (let i = 0; i < 5; i++) {
if (li.parentElement && li.parentElement.tagName === 'LI') {
li = li.parentElement;
break;
}
if (li.parentElement) li = li.parentElement;
}
if (li.tagName === 'LI') li.remove();
});
}
// 隱藏頁尾政策連結(例如隱私權政策、服務條款)
function hidePolicyLinks() {
const policyKeywords = ['隱私政策', '服務條款', '廣告', 'Ad Choices', 'Cookie', 'Meta © 2025', 'Privacy Policy', 'Terms'];
document.querySelectorAll('footer, div[role="contentinfo"]').forEach(container => {
policyKeywords.forEach(kw => {
if (container.textContent.includes(kw)) container.style.display = 'none';
});
});
}
// 隱藏「顯示更多/較少」按鈕
function removeMoreAndLessButtons() {
document.querySelectorAll('[role="button"]').forEach(btn => {
const spans = btn.querySelectorAll('span');
for (const span of spans) {
const text = span.textContent.trim().toLowerCase();
if (moreKeywords.some(kw => text === kw.toLowerCase() || text.includes(kw.toLowerCase()))) {
btn.style.display = 'none';
break;
}
if (lessKeywords.some(kw => text === kw.toLowerCase() || text.includes(kw.toLowerCase()))) {
btn.style.display = 'none';
break;
}
}
});
}
// 嘗試自動展開「顯示更多」左欄選單
function tryExpandOnce() {
if (!isMainSidebarPage()) return;
let found = false;
const btns = Array.from(document.querySelectorAll('nav[role="navigation"] [role="button"], [role=navigation] [role="button"]'));
for (const btn of btns) {
if (btn.offsetParent === null) continue;
const spans = btn.querySelectorAll('span');
for (const span of spans) {
const text = span.textContent.trim().toLowerCase();
if (moreKeywords.some(kw => text === kw.toLowerCase() || text.includes(kw.toLowerCase()))) {
btn.click(); // 模擬點擊展開
found = true;
setTimeout(removeMoreAndLessButtons, 800);
break;
}
}
if (found) break;
}
}
// 一次執行所有需要隱藏的元素處理
function hideOtherElements() {
selectors.forEach(selector => {
document.querySelectorAll(selector).forEach(el => el.style.display = 'none');
});
hideLeftSidebarByText();
hideRightSidebarByTitle();
removeMarketplaceButton();
hidePolicyLinks();
}
// 使用 debounce 控制節流,避免太頻繁操作 DOM
function debounceHideAndExpand() {
clearTimeout(window.__fbCleanerDebounceTimer);
window.__fbCleanerDebounceTimer = setTimeout(() => {
hideOtherElements();
tryExpandOnce();
}, 300);
}
// 頁面載入完成後自動展開左欄
window.addEventListener('load', () => {
if (isMainSidebarPage()) tryExpandOnce();
});
// 初次執行清理
hideOtherElements();
// 監聽頁面變動,動態移除新增的干擾元素
const observer = new MutationObserver(debounceHideAndExpand);
observer.observe(document.body, { childList: true, subtree: true });
})();
/***** === 第二階段:加寬貼文顯示區域(後執行)=== *****/
// 加寬貼文主體容器 (固定寬度 1200px,避免閃爍)
const styleWiden = document.createElement('style');
styleWiden.textContent = `
div.x193iq5w.xvue9z.xq1tmr.x1ceravr {
width: 1200px !important;
max-width: 1200px !important;
box-sizing: border-box !important;
transition: none !important;
will-change: width !important;
}
/* 新增的擴充樣式 */
div.x193iq5w.xgmub6v.x1ceravr {
width: 1200px !important;
`;
document.head.appendChild(styleWiden);
// 標記已加寬貼文避免重複操作
function applyWiden() {
const posts = document.querySelectorAll('div.x193iq5w.xvue9z.xq1tmr.x1ceravr');
posts.forEach(post => {
if (!post.classList.contains('widened')) {
post.classList.add('widened');
// 只靠CSS強制固定寬度,不額外更動DOM
}
});
}
// 初始加寬
applyWiden();
// 建立一個 MutationObserver,用來監聽 DOM 結構的變化(貼文動態載入時觸發)
const widenObserver = new MutationObserver(() => {
// 清除之前尚未執行的延遲操作(防抖機制)
clearTimeout(window.__fbWidenDebounce);
// 設定一個新的延遲操作,在 200 毫秒後執行 applyWiden 函式(加寬貼文)
window.__fbWidenDebounce = setTimeout(applyWiden, 200);
});
// 如果文件已經載入且有 body,就開始監聽整個 body 的 DOM 變化
if (document.body) {
widenObserver.observe(document.body, {
childList: true, // 監聽子節點新增/刪除
subtree: true // 遞迴監聽整個子樹結構
});
}
/***** === 第三階段:影片標題處理 === *****/
// 當影片暫停時顯示標題,播放時隱藏標題
function showTitleWhenPaused(video, titleBar) {
// 綁定影片暫停事件,顯示標題欄
video.addEventListener('pause', () => {
titleBar.style.display = '';
});
// 綁定影片播放事件,隱藏標題欄
video.addEventListener('play', () => {
titleBar.style.display = 'none';
});
}
// 掃描頁面上的影片與標題欄,進行初始化處理
function scan() {
// 嘗試取得影片標題區塊的容器(通常位於影片上方)
const titleBar = document.querySelector('div.x15q7m8w.x1ey2m1c.x78zum5.xdt5ytf');
if (!titleBar) return; // 若找不到標題則不繼續
// 預設一開始先隱藏標題
titleBar.style.display = 'none';
// 對頁面上每個影片元素進行處理
document.querySelectorAll('video').forEach(video => {
showTitleWhenPaused(video, titleBar); // 設定暫停/播放對應的標題顯示邏輯
});
}
// 建立 MutationObserver 監聽整個頁面是否載入新影片或標題
const videoObserver = new MutationObserver(scan);
// 開始監聽整個 body 的變化(影片可能是動態載入的)
videoObserver.observe(document.body, {
childList: true, // 監聽子節點新增/刪除
subtree: true // 遞迴監聽整個子樹結構
});
// 初始執行一次掃描,確保一開始的影片也處理到
scan();
})();