将YouTube影院模式的外观改为网页全屏,按T进入,按T或ESC退出
// ==UserScript==
// @name YouTube FullWindow
// @name:zh-CN YouTube网页全屏
// @name:ja YouTubeフルウィンドウ
// @namespace http://tampermonkey.net/
// @version 1.3
// @description Changes YouTube theater mode appearance to fullwindow, press T to enter, T or ESC to exit
// @description:zh-CN 将YouTube影院模式的外观改为网页全屏,按T进入,按T或ESC退出
// @description:ja YouTubeシアターモードの外観をフルウィンドウに変更、Tで入り、TまたはESCで退出
// @author jo
// @match https://www.youtube.com/*
// @icon https://www.youtube.com/favicon.ico
// @grant none
// @license MIT
// ==/UserScript==
(function() {
'use strict';
let isWebFullscreen = false;
let mastheadObserver = null;
let isHandlingFullscreenFromTheater = false;
let doubleClickHandler = null;
function addFullscreenStyles() {
if (document.getElementById('yt-web-fullscreen-style')) {
return;
}
const style = document.createElement('style');
style.id = 'yt-web-fullscreen-style';
style.textContent = `
/* 影院模式时的全屏样式 */
ytd-watch-flexy[full-bleed-player] #full-bleed-container.ytd-watch-flexy {
position: fixed !important;
top: 0 !important;
left: 0 !important;
z-index: 3000 !important;
width: 100vw !important;
height: 100vh !important;
max-height: 100vh !important;
background: #000 !important;
}
/* 全屏模式样式 */
ytd-watch-flexy[fullscreen] #full-bleed-container.ytd-watch-flexy {
position: fixed !important;
top: 0 !important;
left: 0 !important;
z-index: 3000 !important;
width: 100vw !important;
height: 100vh !important;
max-height: 100vh !important;
background: #000 !important;
}
/* 隐藏页面右侧滚动条 */
.web-fullscreen-active {
overflow: hidden !important;
height: 100% !important;
}
.web-fullscreen-active body {
overflow: hidden !important;
height: 100% !important;
}
/* 确保页面内容正常显示 */
ytd-watch-flexy:not([full-bleed-player]):not([fullscreen]) {
overflow: visible !important;
}
/* 强制显示画中画和影院模式按钮(全屏模式下) */
.ytp-fullscreen .ytp-pip-button,
.ytp-fullscreen .ytp-size-button {
display: inline-block !important;
opacity: 1 !important;
visibility: visible !important;
}
/* 确保按钮在hover状态下也可见 */
.ytp-fullscreen .ytp-pip-button:hover,
.ytp-fullscreen .ytp-size-button:hover {
opacity: 1 !important;
}
`;
document.head.appendChild(style);
console.log('YouTube网页全屏样式已注入');
}
function toggleFullscreenState(enable) {
if (enable === isWebFullscreen) return;
if (enable) {
isWebFullscreen = true;
document.documentElement.classList.add('web-fullscreen-active');
console.log('进入网页全屏模式');
} else {
isWebFullscreen = false;
document.documentElement.classList.remove('web-fullscreen-active');
console.log('退出网页全屏模式');
}
}
// 使用masthead属性检测当前模式
function getCurrentMode() {
const masthead = document.getElementById('masthead');
if (!masthead) return 'default';
if (masthead.hasAttribute('fullscreen')) return 'fullscreen';
if (masthead.hasAttribute('theater')) return 'theater';
return 'default';
}
function toggleTheaterMode() {
const theaterButton = document.querySelector('.ytp-size-button.ytp-button');
if (theaterButton) {
theaterButton.click();
console.log('切换影院模式');
return true;
}
return false;
}
function toggleFullscreen() {
const fullscreenButton = document.querySelector('.ytp-fullscreen-button.ytp-button');
if (fullscreenButton) {
fullscreenButton.click();
console.log('切换全屏模式');
return true;
}
return false;
}
function exitTheaterMode() {
const currentMode = getCurrentMode();
if (currentMode === 'theater') {
return toggleTheaterMode();
}
return false;
}
function handleKeyDown(event) {
// 检查是否在输入框或文本区域中
const activeElement = document.activeElement;
const isTextInput = activeElement.tagName === 'INPUT' ||
activeElement.tagName === 'TEXTAREA' ||
activeElement.isContentEditable;
if (isTextInput) {
return;
}
const currentMode = getCurrentMode();
// T键处理:切换影院模式(网页全屏)
if (event.keyCode === 84) { // T key
event.preventDefault();
event.stopPropagation();
event.stopImmediatePropagation();
console.log('按T键,当前模式:', currentMode);
if (currentMode === 'default') {
// 默认模式 -> 进入影院模式
toggleTheaterMode();
} else if (currentMode === 'theater') {
// 影院模式 -> 退出到默认模式
toggleTheaterMode();
} else if (currentMode === 'fullscreen') {
// 全屏模式 -> 退出全屏,进入影院模式
toggleFullscreen();
setTimeout(() => {
if (getCurrentMode() === 'default') {
toggleTheaterMode();
}
}, 100);
}
}
// F键处理:切换全屏
if (event.keyCode === 70) { // F key
event.preventDefault();
event.stopPropagation();
event.stopImmediatePropagation();
console.log('按F键,当前模式:', currentMode);
if (currentMode === 'default') {
// 默认模式 -> 进入全屏模式
toggleFullscreen();
} else if (currentMode === 'theater') {
// 影院模式 -> 先退出影院模式,再进入全屏
isHandlingFullscreenFromTheater = true;
exitTheaterMode();
setTimeout(() => {
toggleFullscreen();
isHandlingFullscreenFromTheater = false;
}, 100);
} else if (currentMode === 'fullscreen') {
// 全屏模式 -> 退出全屏
toggleFullscreen();
}
}
// ESC键处理:退出到默认视图
if (event.keyCode === 27) { // ESC key
const currentMode = getCurrentMode();
if (currentMode === 'fullscreen' || currentMode === 'theater') {
event.preventDefault();
event.stopPropagation();
event.stopImmediatePropagation();
console.log('按ESC键,退出到默认视图');
if (currentMode === 'fullscreen') {
toggleFullscreen();
} else if (currentMode === 'theater') {
toggleTheaterMode();
}
}
}
}
function observeMastheadChanges() {
if (mastheadObserver) {
mastheadObserver.disconnect();
}
const masthead = document.getElementById('masthead');
if (!masthead) {
setTimeout(observeMastheadChanges, 1000);
return;
}
let lastMode = getCurrentMode();
mastheadObserver = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
if (mutation.type === 'attributes' &&
(mutation.attributeName === 'theater' || mutation.attributeName === 'fullscreen')) {
const currentMode = getCurrentMode();
console.log('模式变化:', currentMode, '之前模式:', lastMode);
// 更新最后模式
lastMode = currentMode;
// 影院模式或全屏模式都启用网页全屏样式
toggleFullscreenState(currentMode !== 'default');
// 全屏模式下强制显示按钮
if (currentMode === 'fullscreen') {
setTimeout(forceShowButtons, 100);
}
}
});
});
mastheadObserver.observe(masthead, {
attributes: true,
attributeFilter: ['theater', 'fullscreen']
});
// 初始状态检查
const currentMode = getCurrentMode();
console.log('初始模式:', currentMode);
lastMode = currentMode;
toggleFullscreenState(currentMode !== 'default');
}
// 强制显示画中画和影院模式按钮
function forceShowButtons() {
const pipButtons = document.querySelectorAll('.ytp-pip-button');
const sizeButtons = document.querySelectorAll('.ytp-size-button');
pipButtons.forEach(button => {
button.style.display = 'inline-block';
button.style.opacity = '1';
button.style.visibility = 'visible';
});
sizeButtons.forEach(button => {
button.style.display = 'inline-block';
button.style.opacity = '1';
button.style.visibility = 'visible';
});
}
// 监听全屏按钮点击,实现从影院模式进入全屏时的拆解操作
function setupFullscreenButtonListener() {
document.addEventListener('click', function(event) {
const target = event.target;
const fullscreenButton = target.closest('.ytp-fullscreen-button.ytp-button');
if (fullscreenButton && getCurrentMode() === 'theater' && !isHandlingFullscreenFromTheater) {
event.preventDefault();
event.stopPropagation();
event.stopImmediatePropagation();
console.log('从影院模式点击全屏按钮,拆解操作');
isHandlingFullscreenFromTheater = true;
// 先退出影院模式,再进入全屏
exitTheaterMode();
setTimeout(() => {
toggleFullscreen();
isHandlingFullscreenFromTheater = false;
}, 100);
} else if (fullscreenButton) {
// 普通情况下的全屏按钮点击
console.log('检测到全屏按钮点击');
// 延迟确保按钮在全屏模式下显示
setTimeout(forceShowButtons, 200);
}
}, true);
}
// 拦截影院模式下的双击全屏
function setupDoubleClickListener() {
// 移除之前的监听器
if (doubleClickHandler) {
document.removeEventListener('dblclick', doubleClickHandler);
}
doubleClickHandler = function(event) {
const currentMode = getCurrentMode();
// 如果在影院模式下双击,拦截并执行拆解操作
if (currentMode === 'theater' && !isHandlingFullscreenFromTheater) {
event.preventDefault();
event.stopPropagation();
event.stopImmediatePropagation();
console.log('拦截影院模式下双击全屏,执行拆解操作');
isHandlingFullscreenFromTheater = true;
// 先退出影院模式,再进入全屏
exitTheaterMode();
setTimeout(() => {
toggleFullscreen();
isHandlingFullscreenFromTheater = false;
}, 100);
}
};
// 使用捕获阶段确保我们先于YouTube处理双击事件
document.addEventListener('dblclick', doubleClickHandler, true);
}
function handlePageChange() {
console.log('检测到页面变化,重新初始化...');
toggleFullscreenState(false);
isHandlingFullscreenFromTheater = false;
addFullscreenStyles();
setTimeout(observeMastheadChanges, 500);
setTimeout(setupFullscreenButtonListener, 1000);
setTimeout(setupDoubleClickListener, 1000);
}
// 初始化函数
function init() {
console.log('初始化YouTube网页全屏脚本');
addFullscreenStyles();
document.addEventListener('keydown', handleKeyDown, true);
observeMastheadChanges();
setupFullscreenButtonListener();
setupDoubleClickListener();
// 监听DOM变化
const domObserver = new MutationObserver(function(mutations) {
let shouldReinit = false;
mutations.forEach(function(mutation) {
if (mutation.type === 'childList') {
mutation.addedNodes.forEach(function(node) {
if (node.nodeType === 1 && node.id === 'masthead') {
shouldReinit = true;
}
});
}
});
if (shouldReinit) setTimeout(handlePageChange, 100);
});
domObserver.observe(document.body, { childList: true, subtree: true });
}
// 监听URL变化
let lastUrl = location.href;
const urlObserver = new MutationObserver(() => {
const url = location.href;
if (url !== lastUrl) {
lastUrl = url;
handlePageChange();
}
});
urlObserver.observe(document, { subtree: true, childList: true });
// 初始化
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址