es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Navegadores basados en Chrome: ScrollTo y vínculos ancla no funcionan.

Estoy tratando de construir un sitio de portfolio donde un ascensor se mueve hacia arriba y cuando llega a un piso, las puertas se abren y se muestra el detalle. Al desplazarse más, las puertas se cierran y cuando llega a un punto determinado, se desplaza suavemente al piso más cercano.

Lo he conseguido hacer funcionar correctamente en Firefox, pero no en los navegadores basados en Chrome, lo cual realmente me está confundiendo. También puedo hacer que el navegador basado en Chrome se mueva a un punto de anclaje o haga scroll hasta ver, pero solo si se activan usando un botón; ¡nunca funcionan cuando el observador de intersección llama al código?

Estoy utilizando el observador de intersección para detectar qué piso es visible e iniciar los eventos de apertura y cierre, y un observador separado para detectar cuando un piso está al 50% en pantalla y hacer scroll hasta el piso más cercano.

Al principio, intenté evitar el segundo observador de intersección usando la propiedad scroll-snap para alinear los pisos, pero eso no funcionó en ningún navegador.

.post-container {
z-index: -2;
min-height: 80vh;
min-width: 100%;
display: flex;
flex-direction: column;
justify-content: start;
scroll-snap-type: y proximity;
}

.post {
z-index: -2;
background-size: cover;
width: 100%;
height: 80vh;
padding-top: 3rem;
padding-bottom: 3rem;
scroll-snap-align: start;
}

Luego intenté usar la función scrollToView(), que funciona perfectamente en Firefox pero no en navegadores basados en Chrome.

const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
entry.target.scrollIntoView({ behavior: ‘smooth’, block: ‘end’ });
}
});
},
{ threshold: 0.5 }
);

También intenté usar los enlaces de anclaje para que el observador de intersección encuentre los pisos, lo cual de nuevo funciona bien en Firefox pero no en Chrome.

const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
move(entry.target.id);
}
});
},
{ threshold: 0.5 }
);

function move(entry) {
window.location.href = ‘#’ + entry;
}

Tengo la sensación de que tal vez el desplazamiento del ratón tiene prioridad sobre el scrollTo y los enlaces de anclaje, pero realmente no entiendo qué está sucediendo.

Cualquier ayuda es muy apreciada, pero ayuda sin jQuery es aún más apreciada.

Muchas gracias,

Geoff

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Solución para el desplazamiento y detección de secciones en un sitio de portfolio

    Como experto en TI especializado en JavaScript, google-chrome, firefox, scroll-snap, js-scrollto, aquí está mi consejo:

    Issue (Problema)
    Estás intentando construir un sitio de portfolio donde un ascensor se mueve hacia arriba y cuando llega a un piso, las puertas se abren y se renderiza el detalle. Al seguir desplazándose, las puertas se cierran y cuando llega a un cierto punto, hace un desplazamiento suave (smooth scroll) hacia el piso más cercano.

    Lo has logrado hacer funcionar correctamente en Firefox, pero no en navegadores basados en Chrome, lo cual te está confundiendo mucho. También puedes hacer que el navegador basado en Chrome se desplace a un punto de anclaje (hash anchor) o scrolltoview, pero solo cuando los activas utilizando un botón; nunca funcionan cuando el observador de intersección llama al código.

    Estás utilizando el observador de intersección para detectar qué piso es visible e iniciar el evento de apertura y cierre, y un observador separado para detectar cuando un piso está al 50% en la pantalla para hacer un desplazamiento (snap) hasta el piso más cercano.

    Primero intentaste evitar el segundo observador de intersección utilizando scroll-snap para alinear los pisos, pero eso no funcionó en ningún navegador. Luego intentaste usar la función scrollToView(), que funciona perfectamente en Firefox pero no en los basados en Chrome. También intentaste usar los enlaces de anclaje para que el observador de intersección localice los pisos, lo cual nuevamente funciona bien en Firefox pero no en Chrome.

    Tienes la sensación de que tal vez el desplazamiento del mouse tiene prioridad sobre scrollTo y los enlaces de anclaje, pero realmente no entiendes lo que está sucediendo.

    Solución
    El problema podría estar en la función scrollIntoView(). Esta función hará que el elemento que se le pase se desplace a la vista, y podría comportarse de manera diferente en diferentes navegadores.

    En lugar de utilizar scrollIntoView(), intenta utilizar window.scrollTo(). Esta función hará que toda la página se desplace a la posición deseada. Aquí tienes un ejemplo de cómo puedes utilizarlo:

    const targetElement = document.getElementById('my-target-element');
    const targetOffsetTop = targetElement.getBoundingClientRect().top + window.pageYOffset;
    window.scrollTo({top: targetOffsetTop, behavior: 'smooth'});
    

    El método getBoundingClientRect() devolverá la posición del elemento objetivo con respecto al viewport. Para obtener la posición con respecto a todo el documento, debes agregar la propiedad scrollTop de la ventana del documento al valor de top del rectángulo delimitador. La propiedad scrollTop te dará la cantidad de píxeles que se han desplazado desde la parte superior del documento.

    Puedes utilizar esta técnica cuando el observador detecte qué sección es visible.

    En cuanto al problema del desplazamiento del mouse, puedes desactivar el desplazamiento temporalmente mientras el ascensor se mueve. Puedes agregar un event listener a los botones que activan el ascensor y, en el manejador de eventos, puedes establecer la propiedad overflow del body en hidden. Esto desactivará el desplazamiento. Después de que el ascensor haya llegado a su destino, puedes restablecer la propiedad overflow en auto para habilitar el desplazamiento.

    Espero que esta solución te ayude a solucionar los problemas que estás teniendo con tu sitio de portfolio sin depender de jQuery.

Comments are closed.