Implementación completa de navbar sticky con menú hamburguesa responsive según especificaciones del template del cliente: **Archivos Modificados:** - header.php: Reescritura completa con navbar Bootstrap 5, sticky positioning, y responsive hamburger menu - functions.php: Agregado require para nav-walker.php - inc/enqueue-scripts.php: Agregado enqueue de custom-style.css y main.js **Archivos Creados:** - assets/css/custom-style.css: Estilos navbar con animaciones (gradient underline, dropdown slideDown, etc.) - assets/js/main.js: JavaScript para scroll effect, active menu highlight, y mobile auto-close - inc/nav-walker.php: Bootstrap 5 Nav Walker para dropdowns WordPress **Características:** ✅ Navbar sticky con transición de sombra al hacer scroll ✅ Gradient underline animation en hover de nav-links ✅ Dropdown menus con animación slideDown ✅ Menú hamburguesa responsive (< 991px) ✅ Auto-close mobile menu al hacer click en enlaces ✅ Active menu item highlighting ✅ Smooth scroll para anchor links ✅ Skip link para accesibilidad ✅ Compatible con WordPress menu system 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
145 lines
4.1 KiB
JavaScript
145 lines
4.1 KiB
JavaScript
/**
|
|
* Main JavaScript - APUS Theme
|
|
*
|
|
* Funcionalidades principales del tema según template del cliente.
|
|
* Incluye: Navbar sticky scroll effect y animaciones.
|
|
*
|
|
* @package Apus_Theme
|
|
* @since 1.0.0
|
|
*/
|
|
|
|
(function() {
|
|
'use strict';
|
|
|
|
/**
|
|
* Navbar Scroll Effect
|
|
* Añade clase 'scrolled' al navbar cuando se hace scroll > 50px
|
|
*/
|
|
function initNavbarScrollEffect() {
|
|
const navbar = document.querySelector('.navbar');
|
|
|
|
if (!navbar) {
|
|
return;
|
|
}
|
|
|
|
// Optimización con throttle para mejor performance
|
|
let ticking = false;
|
|
|
|
function updateNavbar() {
|
|
if (window.scrollY > 50) {
|
|
navbar.classList.add('scrolled');
|
|
} else {
|
|
navbar.classList.remove('scrolled');
|
|
}
|
|
ticking = false;
|
|
}
|
|
|
|
window.addEventListener('scroll', function() {
|
|
if (!ticking) {
|
|
window.requestAnimationFrame(updateNavbar);
|
|
ticking = true;
|
|
}
|
|
});
|
|
|
|
// Ejecutar una vez al cargar por si la página ya tiene scroll
|
|
updateNavbar();
|
|
}
|
|
|
|
/**
|
|
* Highlight Active Menu Item
|
|
* Marca el item del menú correspondiente a la página actual
|
|
*/
|
|
function highlightActiveMenuItem() {
|
|
const currentUrl = window.location.href;
|
|
const navLinks = document.querySelectorAll('.navbar-nav .nav-link');
|
|
|
|
navLinks.forEach(function(link) {
|
|
// Remover active de todos
|
|
link.classList.remove('active');
|
|
|
|
// Agregar active si coincide URL
|
|
if (link.href === currentUrl) {
|
|
link.classList.add('active');
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Mobile Menu Close on Link Click
|
|
* Cierra el menú móvil automáticamente al hacer click en un enlace
|
|
*/
|
|
function initMobileMenuAutoClose() {
|
|
const navbarToggler = document.querySelector('.navbar-toggler');
|
|
const navbarCollapse = document.querySelector('.navbar-collapse');
|
|
const navLinks = document.querySelectorAll('.navbar-nav .nav-link');
|
|
|
|
if (!navbarToggler || !navbarCollapse) {
|
|
return;
|
|
}
|
|
|
|
navLinks.forEach(function(link) {
|
|
link.addEventListener('click', function() {
|
|
// Solo en móvil (cuando el toggler es visible)
|
|
if (window.getComputedStyle(navbarToggler).display !== 'none') {
|
|
const bsCollapse = bootstrap.Collapse.getInstance(navbarCollapse);
|
|
if (bsCollapse) {
|
|
bsCollapse.hide();
|
|
}
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Smooth Scroll for Anchor Links
|
|
* Scroll suave para enlaces ancla (#)
|
|
*/
|
|
function initSmoothScroll() {
|
|
const anchorLinks = document.querySelectorAll('a[href^="#"]');
|
|
|
|
anchorLinks.forEach(function(link) {
|
|
link.addEventListener('click', function(e) {
|
|
const targetId = this.getAttribute('href');
|
|
|
|
// Ignorar enlaces # vacíos o solo #
|
|
if (targetId === '#' || targetId === '') {
|
|
return;
|
|
}
|
|
|
|
const targetElement = document.querySelector(targetId);
|
|
|
|
if (targetElement) {
|
|
e.preventDefault();
|
|
|
|
// Offset por el navbar sticky
|
|
const navbarHeight = document.querySelector('.navbar').offsetHeight;
|
|
const targetPosition = targetElement.getBoundingClientRect().top + window.pageYOffset - navbarHeight - 20;
|
|
|
|
window.scrollTo({
|
|
top: targetPosition,
|
|
behavior: 'smooth'
|
|
});
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Initialize all functions when DOM is ready
|
|
*/
|
|
function init() {
|
|
initNavbarScrollEffect();
|
|
highlightActiveMenuItem();
|
|
initMobileMenuAutoClose();
|
|
initSmoothScroll();
|
|
}
|
|
|
|
// DOM Ready
|
|
if (document.readyState === 'loading') {
|
|
document.addEventListener('DOMContentLoaded', init);
|
|
} else {
|
|
init();
|
|
}
|
|
|
|
})();
|