
Scroll suave en enlaces ancla y activado de enlaces correspondientes
abril 30, 2025 10:09 pm¿Tienes un sitio web con secciones en la misma página y un menú con enlaces tipo #ancla
? Entonces este truco te va a encantar. Vamos a ver cómo hacer scroll animado al pulsar un enlace y cómo detectar qué sección está en pantalla para resaltar el enlace correspondiente del menú con la clase active
.
🧩 1. Scroll suave al hacer clic en enlaces ancla
El siguiente fragmento de código hace que, al pulsar un enlace ancla (como #servicios
, #contacto
, etc.), la página se desplace suavemente hasta esa sección. Añade este código JavaScript a tu tema (por ejemplo en un archivo custom.js
o en el personalizador):
$(document).on("click", 'a[href^="#"]', function (event) {
event.preventDefault();
$("html, body").animate(
{
scrollTop: $($.attr(this, "href")).offset().top - 50,
},
500
);
});
💡 Consejo: El número 50
se puede ajustar para compensar la altura del menú fijo si usas uno.
👁️ 2. Detectar qué sección es visible y activar su enlace en el menú
Este segundo script es aún más interesante. Usando IntersectionObserver
, detectamos cuál de las secciones (.vc_row
, en este ejemplo) es la más visible en el viewport y activamos su enlace correspondiente del menú de navegación (.nav a
):
jQuery(document).ready(function($) {
const navLinks = $('.nav a');
const sections = $('.vc_row');
const visibleSections = {};
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
visibleSections[entry.target.id] = entry.intersectionRatio;
} else {
delete visibleSections[entry.target.id];
}
});
let maxRatio = 0;
let sectionMasVisible = null;
for (const [sectionId, ratio] of Object.entries(visibleSections)) {
if (ratio > maxRatio) {
maxRatio = ratio;
sectionMasVisible = sectionId;
}
}
if (sectionMasVisible) {
navLinks.removeClass('active');
navLinks.filter(`[href="#${sectionMasVisible}"]`).addClass('active');
}
}, {
threshold: construirListaThresholds()
});
sections.each((i, sec) => observer.observe(sec));
function construirListaThresholds() {
let thresholds = [];
for (let i = 0; i <= 1; i += 0.01) {
thresholds.push(i);
}
return thresholds;
}
});
💡 Detalles a tener en cuenta
- Cada sección debe tener un
id
único:id="servicios"
,id="contacto"
, etc. - El selector
.vc_row
se usa en temas con WPBakery. Puedes cambiarlo por.elementor-section
,.seccion
,.bloque
según tu constructor. - El selector
.nav a
debe apuntar al menú que contiene los enlaces ancla.
🧪 Bonus: cómo probarlo
Puedes copiar este código en un archivo .js
dentro de tu tema hijo y cargarlo en functions.php
así:
function cargar_scripts_scroll_menu() {
wp_enqueue_script('scroll-menu', get_stylesheet_directory_uri() . '/js/scroll-menu.js', array('jquery'), null, true);
}
add_action('wp_enqueue_scripts', 'cargar_scripts_scroll_menu');
📥 ¿Te gustaría tenerlo como plugin?
Estamos valorando publicar este código como un plugin gratuito para facilitar su uso sin tocar código. Si te interesa, escríbenos desde el formulario de contacto y le daremos prioridad.
Los comentarios están cerrados.