您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Integrates the live chat into the mobile version of YouTube
当前为
// ==UserScript== // @name Live Chat on YouTube Mobile // @namespace http://tampermonkey.net/ // @version 1.1 // @description Integrates the live chat into the mobile version of YouTube // @match https://m.youtube.com/* // @grant none // @license MIT // ==/UserScript== (function() { 'use strict'; const button = document.createElement('button'); button.innerText = '💬'; button.style.position = 'fixed'; button.style.bottom = '64px'; button.style.right = '20px'; button.style.zIndex = '9999'; button.style.padding = '10px'; button.style.backgroundColor = '#ff0000'; button.style.color = '#fff'; button.style.border = 'none'; button.style.borderRadius = '50%'; button.style.width = '45px'; button.style.height = '45px'; button.style.fontSize = '20px'; button.style.lineHeight = '0'; button.style.boxShadow = '0 3px 6px rgba(0,0,0,0.3)'; button.style.cursor = 'pointer'; document.body.appendChild(button); const chatContainer = document.createElement('div'); chatContainer.style.display = 'none'; chatContainer.style.position = 'fixed'; chatContainer.style.width = '100%'; chatContainer.style.top = '250px'; chatContainer.style.bottom = '0'; chatContainer.style.height = 'auto'; chatContainer.style.left = '0'; chatContainer.style.right = '0'; chatContainer.style.borderTop = '1px solid #ccc'; chatContainer.style.backgroundColor = '#fff'; chatContainer.style.zIndex = '9998'; chatContainer.style.overflow = 'auto'; const chatIframe = document.createElement('iframe'); chatIframe.style.width = '100%'; chatIframe.style.height = '100%'; chatIframe.style.border = 'none'; chatIframe.style.maxWidth = '100%'; let isIframeLoaded = false; let observer = null; let currentVideoId = null; const closeChat = () => { if (chatContainer.style.display !== 'none') { chatContainer.style.display = 'none'; button.innerText = '💬'; } if (observer) { observer.disconnect(); observer = null; } }; const isVideoPage = () => { return window.location.pathname === '/watch' && window.location.search.includes('v='); }; const applyIframeStyles = () => { if (!isIframeLoaded) { try { const iframeDocument = chatIframe.contentWindow.document; const style = iframeDocument.createElement('style'); style.textContent = ` .style-scope.yt-live-chat-text-message-renderer { font-size: 12px !important; } .style-scope.yt-live-chat-text-message-renderer #author-name { font-size: 12px !important; } `; iframeDocument.head.appendChild(style); isIframeLoaded = true; } catch (e) { } } }; const startVideoObserver = () => { const videoElement = document.querySelector('video'); if (!videoElement) return; const playerContainer = videoElement.closest('div'); if (!playerContainer) return; if (observer) observer.disconnect(); observer = new MutationObserver((mutationsList, obs) => { let wasRemoved = false; mutationsList.forEach(mutation => { mutation.removedNodes.forEach(node => { if (node === playerContainer || (node.contains && node.contains(playerContainer))) { wasRemoved = true; } }); }); if (wasRemoved) { closeChat(); obs.disconnect(); } }); const config = { childList: true, subtree: true }; const parentOfPlayerContainer = playerContainer.parentNode; if (parentOfPlayerContainer) { observer.observe(parentOfPlayerContainer, config); } }; button.onclick = function() { if (chatContainer.style.display === 'none') { const videoIdMatch = window.location.search.match(/v=([^&]+)/); if (videoIdMatch) { const videoId = videoIdMatch[1]; if (!chatIframe.parentElement) { chatContainer.appendChild(chatIframe); document.body.appendChild(chatContainer); chatIframe.onload = applyIframeStyles; } if (videoId !== currentVideoId) { const newChatSrc = `https://www.youtube.com/live_chat?v=${videoId}&embed_domain=${window.location.hostname}`; chatIframe.src = newChatSrc; currentVideoId = videoId; isIframeLoaded = false; } const videoPlayer = document.querySelector('video'); if (videoPlayer) { const videoRect = videoPlayer.getBoundingClientRect(); const isVertical = videoRect.height > videoRect.width && videoRect.height > 100; if (isVertical) { chatContainer.style.top = '50%'; chatContainer.style.height = '50%'; } else { chatContainer.style.top = `${videoRect.bottom}px`; chatContainer.style.height = 'auto'; } chatContainer.style.bottom = '0'; } else { chatContainer.style.top = '250px'; chatContainer.style.height = 'auto'; } chatContainer.style.display = 'block'; button.innerText = '✖️'; chatIframe.focus(); startVideoObserver(); } else { alert('No se pudo encontrar el ID del video.'); } } else { closeChat(); } }; const updateButtonVisibility = () => { button.style.display = isVideoPage() ? 'block' : 'none'; if (!isVideoPage()) { closeChat(); currentVideoId = null; } if (chatContainer.style.display !== 'none') { const videoPlayer = document.querySelector('video'); if (videoPlayer) { const videoRect = videoPlayer.getBoundingClientRect(); const isVertical = videoRect.height > videoRect.width && videoRect.height > 100; if (isVertical) { chatContainer.style.top = '50%'; chatContainer.style.height = '50%'; } else { chatContainer.style.top = `${videoRect.bottom}px`; chatContainer.style.height = 'auto'; } } } }; setInterval(updateButtonVisibility, 500); updateButtonVisibility(); })();