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_rowse usa en temas con WPBakery. Puedes cambiarlo por.elementor-section,.seccion,.bloquesegún tu constructor. - El selector
.nav adebe 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.