El Atributo ONSCROLL

El evento onscroll se dispara cuando un elemento o la ventana del navegador se desplaza.

El evento onscroll se dispara cuando un elemento o la ventana del navegador se desplaza. Es esencial para crear efectos dinámicos, cargar contenido bajo demanda y mejorar la interacción del usuario.


???? Sintaxis básica

html
Copy
<!-- En la ventana del navegador -->
<body onscroll="manejarScroll()">

<!-- En un elemento específico -->
<div id="contenedor" onscroll="manejarScrollElemento(event)">
  <!-- Contenido desplazable -->
</div>
javascript
Copy
// Método recomendado (JavaScript puro)
window.addEventListener("scroll", () => {
  // Lógica para scroll en la ventana
});

document.getElementById("contenedor").addEventListener("scroll", (event) => {
  // Lógica para scroll en el elemento
});

???? Propiedades clave

  • window.scrollY: Píxeles desplazados verticalmente.

  • window.scrollX: Píxeles desplazados horizontalmente.

  • element.scrollTop: Desplazamiento vertical interno de un elemento.

  • element.scrollHeight: Altura total del contenido (incluyendo lo no visible).

  • element.clientHeight: Altura visible del elemento.


???? Ejemplos prácticos

1. Barra de progreso de desplazamiento

html
Copy
<div class="progress-bar">
  <div id="progress" class="progress"></div>
</div>

<script>
window.addEventListener("scroll", () => {
  const alturaTotal = document.documentElement.scrollHeight - window.innerHeight;
  const progreso = (window.scrollY / alturaTotal) * 100;
  document.getElementById("progress").style.width = `${progreso}%`;
});
</script>

<style>
.progress-bar {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 4px;
  background: #eee;
}
.progress {
  height: 100%;
  background: #2ecc71;
  transition: width 0.3s ease;
}
</style>

2. Navegación sticky con efecto

html
Copy
<nav id="navbar">Menú de navegación</nav>

<script>
window.addEventListener("scroll", () => {
  const navbar = document.getElementById("navbar");
  navbar.style.background = window.scrollY > 100 ? "#2c3e50" : "transparent";
  navbar.style.boxShadow = window.scrollY > 100 ? "0 2px 10px rgba(0,0,0,0.1)" : "none";
});
</script>

<style>
#navbar {
  position: fixed;
  top: 0;
  width: 100%;
  padding: 20px;
  transition: all 0.3s;
}
</style>

3. Carga infinita (infinite scroll)

javascript
Copy
window.addEventListener("scroll", () => {
  const umbral = 500; // Cargar 500px antes del final
  const { scrollTop, scrollHeight, clientHeight } = document.documentElement;
  
  if (scrollTop + clientHeight >= scrollHeight - umbral) {
    cargarMasContenido();
  }
});

async function cargarMasContenido() {
  // Simular carga de datos desde API
  const nuevosDatos = await fetch('/api/contenido?pagina=2');
  // Agregar contenido al DOM
}

???? Técnicas avanzadas

1. Scroll suave con comportamiento personalizado

javascript
Copy
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
  anchor.addEventListener("click", (e) => {
    e.preventDefault();
    const target = document.querySelector(anchor.getAttribute("href"));
    target.scrollIntoView({
      behavior: "smooth",
      block: "start"
    });
  });
});

2. Animaciones al hacer scroll (Scroll Reveal)

javascript
Copy
const elementos = document.querySelectorAll(".animar-al-scroll");

function verificarScroll() {
  elementos.forEach(elemento => {
    const posicion = elemento.getBoundingClientRect().top;
    if (posicion < window.innerHeight * 0.8) {
      elemento.classList.add("visible");
    }
  });
}

window.addEventListener("scroll", verificarScroll);
window.addEventListener("load", verificarScroll);

3. Parallax avanzado

html
Copy
<div class="parallax" data-velocidad="0.5"></div>

<script>
window.addEventListener("scroll", () => {
  const elementos = document.querySelectorAll(".parallax");
  elementos.forEach(elemento => {
    const velocidad = parseFloat(elemento.dataset.velocidad);
    const desplazamiento = window.scrollY * velocidad;
    elemento.style.transform = `translateY(${desplazamiento}px)`;
  });
});
</script>

<style>
.parallax {
  height: 100vh;
  background: url('imagen.jpg') center/cover fixed;
  transition: transform 0.3s ease-out;
}
</style>

⚠️ Consideraciones de rendimiento

  1. Debounce/Throttle:

    javascript
    Copy
    let esperando = false;
    window.addEventListener("scroll", () => {
      if (!esperando) {
        requestAnimationFrame(() => {
          // Código aquí
          esperando = false;
        });
        esperando = true;
      }
    });
  2. Usar Intersection Observer para elementos:

    javascript
    Copy
    const observer = new IntersectionObserver((entries) => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          entry.target.classList.add("visible");
        }
      });
    }, { threshold: 0.5 });
    
    document.querySelectorAll(".oculto").forEach(el => observer.observe(el));
  3. Evitar Forced Synchronous Layouts:

    javascript
    Copy
    // Mal: Provoca múltiples cálculos de layout
    for (let i = 0; i < elementos.length; i++) {
      elementos[i].style.width = window.scrollY + "px";
    }
    
    // Bien: Agrupar lecturas/escrituras
    const scrollY = window.scrollY;
    elementos.forEach(el => el.style.width = scrollY + "px");

???? Casos de uso comunes

  • Menús sticky que cambian al hacer scroll

  • Lazy loading de imágenes/vídeos

  • Scrollspy para resaltar secciones activas

  • Efectos de aparición al desplazarse

  • Controles de scroll personalizados

  • Navegación por secciones


???? Conclusión

El atributo onscroll permite:

  • Crear interfaces dinámicas y responsivas

  • Mejorar la experiencia de navegación

  • Optimizar el rendimiento de carga

  • Implementar efectos visuales avanzados

Ejemplo final avanzado (Scroll personalizado):

html
Copy
<div id="contenedor" class="custom-scroll">
  <!-- Contenido largo -->
</div>

<script>
const contenedor = document.getElementById("contenedor");
let isScrolling = false;

contenedor.addEventListener("scroll", () => {
  if (!isScrolling) {
    isScrolling = true;
    requestAnimationFrame(() => {
      // Efectos suaves durante el scroll
      isScrolling = false;
    });
  }
});

// Scroll programático suave
function scrollToPosition(posicion) {
  contenedor.scrollTo({
    top: posicion,
    behavior: "smooth"
  });
}
</script>

<style>
.custom-scroll {
  scroll-behavior: smooth;
  overflow-y: scroll;
  scrollbar-width: thin;
  scrollbar-color: #2ecc71 #f1f1f1;
}
</style>

Con estos conceptos, podrás implementar scrolls interactivos y optimizados en tus proyectos web. ¡Experimenta con diferentes técnicas! ????