Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

283
Views
Buscando una forma mejor (más eficiente) de probar la posición de desplazamiento

Este es un proyecto de Javascript, utilizando la biblioteca jQuery.

Tengo una barra adhesiva que me gustaría mostrar siempre que la ventana del navegador esté debajo de una determinada posición de página y, de lo contrario, ocultarla. Su ID es #sticky-atc-bar .

La posición de la página está determinada por la parte superior de un elemento con clase .product-section .

Basado en la investigación sobre cómo hacer esto, originalmente se me ocurrió el siguiente JS.

 $( document ).ready(function() { $('#sticky-atc-bar').hide(); var section = $(".product-section"); var offsetSection = section.offset().top; //check for top property $(function() { $(window).scroll(function() { console.log('Scroll Event'); if ($(window).scrollTop() >= offsetSection) { // reached product section console.log('True:'); $('#sticky-atc-bar').show(); } else { // not reached product section console.log('False'); $('#sticky-atc-bar').hide(); } }); }); });

Esto funciona. Sin embargo, soy consciente de que genera una gran cantidad de eventos de desplazamiento, todo el tiempo que el usuario interactúa con la página. Sabiendo que eso es muy ineficiente, busqué enfoques alternativos. En el camino leí este artículo llamado "Aprendiendo de Twitter", que tenía mucho sentido.

También encontré esta solución para un requisito similar. Mi versión de ese código es:

 var target = $(".product-section").offset().top, timeout = null; $('#sticky-atc-bar').hide(); $(window).scroll(function () { if (!timeout) { timeout = setTimeout(function () { console.log('scroll'); clearTimeout(timeout); timeout = null; if ($(window).scrollTop() >= target) { $('#sticky-atc-bar').show(); } else { $('#sticky-atc-bar').hide(); } }, 250); } });

Lo configuré en este jsFiddle y funciona.

Sin embargo... Todavía genera un número significativo de eventos. Simplemente se han reducido a un evento cada 250 ms, es decir, 4 cada segundo.

Lo que me gustaría saber es si hay una mejor manera de hacerlo. Dicho de otra manera, además de cambiar el tiempo de espera en esta segunda pieza de código, ¿puedo reducir esta operación a incluso menos eventos? ¿Y es eso necesario en este punto, o un evento cada 250 ms no es un impacto significativo?

about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

Aquí tienes: https://jsfiddle.net/son0azfj/

 var productEl = document.querySelector('.product-section') var stickyEl = document.querySelector('#sticky-atc-bar') // check if we have elements if (productEl && stickyEl) { // create an observer object, binding toggleDisplayFactory to it var observer = new IntersectionObserver(toggleDisplayFactory(stickyEl)) // observe the product element observer.observe(productEl) } // [1] create a named function which accepts an element... function toggleDisplayFactory(element) { // and returns a function - the handler that IntersectionObserver expects return function handler(entries) { // determine if the observed element is in the viewport or not var isInViewPort = Boolean(entries.find(entry => entry.intersectionRatio > 0)) /** * if in the viewport: * we want the element passed in at [1] to use it's own styles, ie remove the inline style property * else: * we want the element to inherit its default display property (eg block, inline, inline-block, etc.) and thus be visible */ var display = isInViewPort ? null : 'inherit' // set the display property of the element passed in at [1] element.style.display = display } }
  1. use InterSectionObserver para observar la posición de un elemento con respecto a la ventana gráfica. Use la posición de ese elemento en la ventana gráfica para "hacer otra cosa", es decir, mostrar/ocultar otro elemento
  2. evite setTimeout para manipular el DOM; use requestAnimationFrame en su lugar (no es necesario aquí)
  3. evite consultar elementos DOM repetidamente: obténgalos una vez y haga referencia a ellos donde deben manipularse
  4. prefiera establecer los valores predeterminados en CSS, y luego en JS anule una propiedad específica en línea, eliminando la propiedad cuando ya no la necesite

Razonamiento:

IntersectionObserver le permite observar un elemento arbitrario con respecto a su posición en la ventana gráfica, en lugar de un evento de desplazamiento que se activa rápidamente a medida que uno se desplaza. Los eventos que activa un elemento observado solo se activan cuando cambia su posición relativa a la ventana gráfica

setTimeout : si tuviera que usar un tiempo de espera, necesitaría pensar en algún número que sea apropiado para usar al usar setTimeout . ¿Cómo haces esto? Bueno, solo puedes adivinar... tendrías que usar un número mágico. requestAnimationFrame en cambio sabe cuándo el DOM está listo para volver a renderizar y calcular el diseño, no se requieren números mágicos


Enlaces:

  • InterSecciónObservador
  • requestAnimationFrame

EDITAR: Siéntase libre de reemplazar document.querySelector con $(selector) - el resto del código funcionará como está.

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!