1/** 2 * SpinnerLoader - Inyección inmediata del loading spinner 3 * 4 * Este script se ejecuta inmediatamente cuando se carga (sin defer), 5 * inyectando el spinner en el DOM antes de que cualquier otro contenido se renderice. 6 * 7 * IMPORTANTE: Este script debe incluirse en el <head> SIN el atributo defer: 8 * <script src="./js/spinner-loader.js"></script> 9 */ 10 11(function() { 12 'use strict'; 13 14 // Detectar idioma basado en la URL o query param para mostrar el mensaje correcto 15 const detectLanguage = function() { 16 // Prioridad 1: Query param (?lang=en) 17 const urlParams = new URLSearchParams(window.location.search); 18 const langParam = urlParams.get('lang'); 19 if (langParam === 'en' || langParam === 'es') { 20 return langParam; 21 } 22 23 // Prioridad 2: URL path (/en/) 24 const pathname = window.location.pathname; 25 if (pathname.includes('/en/')) { 26 return 'en'; 27 } 28 29 // Default: español 30 return 'es'; 31 }; 32 33 // Mensajes del spinner por idioma 34 const messages = { 35 es: 'Cargando...', 36 en: 'Loading...' 37 }; 38 39 const language = detectLanguage(); 40 const spinnerMessage = messages[language]; 41 42 // HTML del spinner con estilos inline para renderizado inmediato 43 const spinnerHTML = ` 44 <div id="framework-loading" style=" 45 position: fixed; 46 top: 0; 47 left: 0; 48 width: 100%; 49 height: 100%; 50 background: rgba(255, 255, 255, 0.95); 51 display: flex; 52 flex-direction: column; 53 justify-content: center; 54 align-items: center; 55 z-index: 9999; 56 visibility: visible !important; 57 opacity: 1 !important; 58 "> 59 <div style=" 60 width: 50px; 61 height: 50px; 62 border: 3px solid #f3f3f3; 63 border-top: 3px solid #007cba; 64 border-radius: 50%; 65 animation: framework-spin 1s linear infinite; 66 margin-bottom: 20px; 67 "></div> 68 <div style=" 69 font-family: 'Raleway', sans-serif; 70 font-size: 16px; 71 color: #333; 72 ">${spinnerMessage}</div> 73 </div> 74 <style> 75 @keyframes framework-spin { 76 0% { transform: rotate(0deg); } 77 100% { transform: rotate(360deg); } 78 } 79 /* Asegurar que el spinner sea visible incluso si body está oculto */ 80 #framework-loading { 81 visibility: visible !important; 82 opacity: 1 !important; 83 } 84 </style> 85 `; 86 87 // Inyectar spinner inmediatamente usando document.write 88 // Esto funciona porque el script se ejecuta durante el parsing del HTML 89 document.write(spinnerHTML); 90 91 // Log para debugging (solo en desarrollo) 92 if (console && console.log) { 93 console.log('[SpinnerLoader] Loading spinner injected for language:', language); 94 } 95 96 // Exponer función global para ocultar el spinner 97 window.hideFrameworkSpinner = function(fadeOutDuration) { 98 fadeOutDuration = fadeOutDuration || 500; 99 const spinner = document.getElementById('framework-loading'); 100 101 if (spinner) { 102 spinner.style.opacity = '0'; 103 spinner.style.transition = 'opacity ' + fadeOutDuration + 'ms ease-out'; 104 105 setTimeout(function() { 106 if (spinner.parentNode) { 107 spinner.parentNode.removeChild(spinner); 108 } 109 }, fadeOutDuration); 110 111 if (console && console.log) { 112 console.log('[SpinnerLoader] Spinner hidden'); 113 } 114 } 115 }; 116 117})();
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.