Files
roi-theme/wp-content/themes/apus-theme/assets/js/main.js
FrankZamora 5440f23512 Implementar navbar sticky con Bootstrap 5 y animaciones - Issue #7
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>
2025-11-04 16:27:54 -06:00

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();
}
})();