/** * Top Notification Bar Script * Issue #39 * * Maneja el cierre de la barra de notificación y el almacenamiento * de la preferencia del usuario mediante cookies. * * @package ROI_Theme * @since 1.0.0 */ (function() { 'use strict'; /** * Inicialización cuando el DOM está listo */ document.addEventListener('DOMContentLoaded', function() { initNotificationBar(); }); /** * Inicializa la funcionalidad de la barra de notificación */ function initNotificationBar() { const notificationBar = document.getElementById('topNotificationBar'); const closeBtn = document.querySelector('.btn-close-notification'); const navbar = document.querySelector('.navbar'); // Verificar que existan los elementos necesarios if (!notificationBar || !closeBtn) { return; } // Event listener para el botón de cerrar closeBtn.addEventListener('click', function() { closeNotificationBar(notificationBar, navbar); }); // Permitir cerrar con la tecla Escape document.addEventListener('keydown', function(e) { if (e.key === 'Escape' && notificationBar.style.display !== 'none') { closeNotificationBar(notificationBar, navbar); } }); // Ajustar el scroll inicial si la barra está visible adjustInitialScroll(notificationBar); } /** * Cierra la barra de notificación con animación * * @param {HTMLElement} notificationBar - Elemento de la barra de notificación * @param {HTMLElement} navbar - Elemento del navbar */ function closeNotificationBar(notificationBar, navbar) { // Ocultar barra con animación de slide up notificationBar.style.transition = 'transform 0.3s ease, opacity 0.3s ease'; notificationBar.style.transform = 'translateY(-100%)'; notificationBar.style.opacity = '0'; // Esperar a que termine la animación antes de ocultar completamente setTimeout(function() { notificationBar.style.display = 'none'; document.body.classList.add('notification-dismissed'); // Ajustar navbar suavemente if (navbar) { navbar.style.transition = 'top 0.3s ease'; navbar.style.top = '0'; } // Guardar cookie por 7 días setCookie('roinotification_dismissed', '1', 7); // Disparar evento personalizado para otros scripts const event = new CustomEvent('notificationBarClosed', { detail: { timestamp: Date.now() } }); document.dispatchEvent(event); }, 300); } /** * Establece una cookie con nombre, valor y días de expiración * * @param {string} name - Nombre de la cookie * @param {string} value - Valor de la cookie * @param {number} days - Días hasta la expiración */ function setCookie(name, value, days) { const expiryDate = new Date(); expiryDate.setDate(expiryDate.getDate() + days); const cookie = name + '=' + encodeURIComponent(value) + '; expires=' + expiryDate.toUTCString() + '; path=/' + '; SameSite=Lax'; document.cookie = cookie; } /** * Ajusta el scroll inicial para compensar la altura de la barra * * @param {HTMLElement} notificationBar - Elemento de la barra de notificación */ function adjustInitialScroll(notificationBar) { // Si hay un hash en la URL, reajustar el scroll para compensar la altura if (window.location.hash) { setTimeout(function() { const target = document.querySelector(window.location.hash); if (target) { const barHeight = notificationBar.offsetHeight; const navbarHeight = document.querySelector('.navbar')?.offsetHeight || 0; const offset = barHeight + navbarHeight; window.scrollTo({ top: target.offsetTop - offset, behavior: 'smooth' }); } }, 100); } } /** * Función helper para obtener el valor de una cookie * * @param {string} name - Nombre de la cookie * @return {string|null} - Valor de la cookie o null si no existe */ function getCookie(name) { const nameEQ = name + '='; const cookies = document.cookie.split(';'); for (let i = 0; i < cookies.length; i++) { let cookie = cookies[i].trim(); if (cookie.indexOf(nameEQ) === 0) { return decodeURIComponent(cookie.substring(nameEQ.length)); } } return null; } })();