您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Personaliza la cantidad de elementos por fila en el feed de YouTube y los shorts.
// ==UserScript== // @name Perzonalizar columnas de videos y shorts en youtube. // @name:en Row Customizer for YouTube Feeds and Shorts // @namespace EterveNallo // @version 1.1 // @description Personaliza la cantidad de elementos por fila en el feed de YouTube y los shorts. // @description:en Customize the number of items per row in your YouTube feed and Shorts. // @author EterveNallo // @license MIT // @match https://www.youtube.com/* // @grant GM_addStyle // @grant GM_registerMenuCommand // @grant GM_getValue // @grant GM_setValue // ==/UserScript== (function () { 'use strict'; // Valores por defecto o cargados let configFeedEnabled = GM_getValue('configFeedEnabled', true); let feedCount = GM_getValue('feedCount', 4); let configShortsEnabled = GM_getValue('configShortsEnabled', true); let hideShorts = GM_getValue('hideShorts', false); let shortsCount = GM_getValue('shortsCount', 4); // Aplicar estilos CSS dinámicamente function applyStyles() { const style = document.createElement('style'); style.id = 'custom-youtube-style'; style.textContent = ''; if (configFeedEnabled) { style.textContent += ` ytd-rich-grid-renderer.style-scope.ytd-two-column-browse-results-renderer { --ytd-rich-grid-items-per-row: ${feedCount} !important; } `; } if (configShortsEnabled) { style.textContent += ` ytd-rich-section-renderer.style-scope.ytd-rich-grid-renderer { --ytd-rich-grid-slim-items-per-row: ${shortsCount} !important; --ytd-rich-grid-game-cards-per-row: ${shortsCount} !important; } `; } document.getElementById('custom-youtube-style')?.remove(); document.head.appendChild(style); } // Aplicar cambios a los shorts function applyShortsBehavior() { if (!configShortsEnabled) return; const container = document.querySelector('#contents-container.ytd-rich-shelf-renderer'); if (!container) return; const shorts = container.querySelectorAll('ytd-rich-item-renderer'); let visibleCount = 0; shorts.forEach((short, index) => { if (hideShorts) { short.style.display = 'none'; return; } short.style.display = ''; if (visibleCount < shortsCount) { if (short.hasAttribute('hidden')) { short.removeAttribute('hidden'); short.setAttribute('style', ''); } visibleCount++; } else { short.setAttribute('hidden', ''); } }); } // Crear interfaz para Feed function createFeedUI() { closeAllUI(); const container = document.createElement('div'); container.id = 'feed-config-ui'; container.style.cssText = uiStyle(); container.innerHTML = ` <h3>🧩 Configurar Feed</h3> <label><strong>¿Configurar?</strong> <select id="feed-enable"> <option value="true" ${configFeedEnabled ? 'selected' : ''}>Sí</option> <option value="false" ${!configFeedEnabled ? 'selected' : ''}>No</option> </select> </label><br><br> <label><strong>🎚 Cantidad por fila:</strong><br> <input type="range" min="3" max="10" value="${feedCount}" id="feed-range"> <span id="feed-range-value">${feedCount}</span> </label><br><br> <small>🔄 Recargue la página para aplicar cambios completos</small><br><br> <button id="close-feed-ui">Cerrar</button> `; document.body.appendChild(container); document.getElementById('feed-enable').addEventListener('change', (e) => { configFeedEnabled = e.target.value === 'true'; GM_setValue('configFeedEnabled', configFeedEnabled); applyStyles(); }); document.getElementById('feed-range').addEventListener('input', (e) => { feedCount = parseInt(e.target.value); GM_setValue('feedCount', feedCount); document.getElementById('feed-range-value').innerText = feedCount; applyStyles(); }); document.getElementById('close-feed-ui').addEventListener('click', () => { closeAllUI(); }); } // Crear interfaz para Shorts function createShortsUI() { closeAllUI(); const container = document.createElement('div'); container.id = 'shorts-config-ui'; container.style.cssText = uiStyle(); container.innerHTML = ` <h3>🎬 Configurar Shorts</h3> <label><strong>✔ Activar script:</strong> <input type="checkbox" id="shorts-toggle" ${configShortsEnabled ? 'checked' : ''}></label><br><br> <label><strong>🙈 Ocultar shorts:</strong> <select id="shorts-visibility"> <option value="visible" ${!hideShorts ? 'selected' : ''}>Visible</option> <option value="hidden" ${hideShorts ? 'selected' : ''}>Oculto</option> </select><br><br> <label><strong>🎚 Shorts visibles:</strong><br> <input type="range" min="3" max="9" value="${shortsCount}" id="shorts-range"> <span id="shorts-range-value">${shortsCount}</span> </label><br><br> <small>🔄 Recargue la página para aplicar cambios completos</small><br><br> <button id="close-shorts-ui">Cerrar</button> `; document.body.appendChild(container); document.getElementById('shorts-toggle').addEventListener('change', (e) => { configShortsEnabled = e.target.checked; GM_setValue('configShortsEnabled', configShortsEnabled); applyStyles(); applyShortsBehavior(); }); document.getElementById('shorts-visibility').addEventListener('change', (e) => { hideShorts = e.target.value === 'hidden'; GM_setValue('hideShorts', hideShorts); applyShortsBehavior(); }); document.getElementById('shorts-range').addEventListener('input', (e) => { shortsCount = parseInt(e.target.value); GM_setValue('shortsCount', shortsCount); document.getElementById('shorts-range-value').innerText = shortsCount; applyStyles(); applyShortsBehavior(); }); document.getElementById('close-shorts-ui').addEventListener('click', () => { closeAllUI(); }); } // Estilo compartido function uiStyle() { return ` position: fixed; top: 100px; right: 20px; z-index: 9999; background: #111; color: white; border: 2px solid #555; border-radius: 10px; padding: 15px; font-family: sans-serif; font-size: 14px; max-width: 240px; `; } // Cerrar interfaces function closeAllUI() { document.getElementById('feed-config-ui')?.remove(); document.getElementById('shorts-config-ui')?.remove(); } // Comandos del menú de Tampermonkey GM_registerMenuCommand("Configurar Feed - YouTube", createFeedUI); GM_registerMenuCommand("Configurar Shorts - YouTube", createShortsUI); // Activar estilos y comportamiento al cargar window.addEventListener('load', () => { applyStyles(); applyShortsBehavior(); }); // Observer por si carga dinámica const observer = new MutationObserver(() => { applyShortsBehavior(); }); observer.observe(document.body, { childList: true, subtree: true }); })();