Tengo una tabla de contenido con id #TableOfContents en la que cada href apunta a h2 o h3.
El problema que tengo es que una vez que el observador de intersección observa el Encabezado, h2 o h3, la Entrada para eso se resalta agregando la clase side-active para ese enlace en #TableOfContents , pero tan pronto como el contenido largo (como el párrafo p ) después de que el encabezado aparece en la ventana gráfica, se elimina el resaltado de esa sección ya que el encabezado no está en la ventana gráfica.
Esto es un problema ya que quiero que la sección (h2, h3) siga resaltada hasta que el próximo h2 o h3 no cruce la mitad de la ventana gráfica.
¿Que puedo hacer?
window.addEventListener('DOMContentLoaded', () => { const observer = new IntersectionObserver(entries => { entries.forEach(entry => { const id = entry.target.getAttribute('id'); if (entry.intersectionRatio > 0) { document.querySelector(`#TableOfContents a[href="#${id}"]`).classList.add('side-active'); } else { document.querySelector(`#TableOfContents a[href="#${id}"]`).classList.remove('side-active'); } }); }); toc = document.querySelectorAll('#TableOfContents a'); // get content so that link refer to it toc.forEach(function (link) { var id = link.getAttribute("href"); var element = document.querySelector(id); observer.observe(element); }); });Entonces, la cosa era que necesitábamos calcular containerBottom por:
agregando la parte superior del contenedor actual + la parte superior del siguiente contenedor
O si es el último contenedor entonces,
la parte superior del contenedor actual + su altura exterior ()
Una vez que; si el i-ésimo contenedor está en la posición de desplazamiento, agregue una clase y elimine la clase de todos los contenedores anteriores al i-ésimo contenedor (línea n. ° 18-21) ( bucle inverso )
$(function () { // Table of contents (`ul`) that contains `a` tag in `li` which we want to highlight var sectionIds = $('#TableOfContents a'); $(document).on('scroll', function(){ sectionIds.each(function(i, e){ var container = $(this).attr('href'); var containerOffset = $(container).offset().top; // container's top var nextContainer = $(sectionIds[i+1]).attr('href') if (i != sectionIds.length-1) { // if this container isn't last container var containerHeight = $(nextContainer).offset().top; } else { // last container's height will be outerHeight var containerHeight = $(container).outerHeight(); } var containerBottom = containerOffset + containerHeight; var scrollPosition = $(document).scrollTop(); if(scrollPosition < containerBottom - 20 && scrollPosition >= containerOffset - 20){ for (var j = i; j >= 0; j--) { $(sectionIds[j]).removeClass('active'); } $(sectionIds[i]).addClass('active'); } else{ $(sectionIds[i]).removeClass('active'); } }); }); });h1 ) que está resaltado permanezca resaltado aunque el título no esté en la ventana gráfica hasta que aparezca el siguiente subtítulo ( "Distancia de un punto desde una línea" ).