javascript - rojo - Cómo capturar todos los eventos de desplazamiento en una página sin adjuntar un controlador de desplazamiento de desplazamiento a cada contenedor único
contenedor verde (4)
* ... grillos cantando ... *
Bien, supongo que esta pregunta no va a obtener ningún amor de stackoverflow, por lo que también podría responder mi propia pregunta en cuanto a la mejor solución que he encontrado hasta ahora, en caso de que otro usuario tropiece con esta pregunta:
La mejor solución que he encontrado es capturar "onmousedown" y "onkeydown" para el elemento BODY: estos eventos se propagan y, por lo tanto, si un usuario intenta mover una barra de desplazamiento en la página, estas funciones globales se activarán como un elemento. producto. Luego, en estas funciones, simplemente busque event.target y adjunte un evento "onscroll" temporal a esos objetos hasta que el mouse / tecla vuelva a estar "arriba". Usando ese método, puede evitar la "infestación de controladores" y aún capturar globalmente todos los eventos "onscroll". (Creo que esto también funcionará para el desplazamiento de la "rueda del ratón", pero mi investigación sobre esa arruga final aún está pendiente).
Considere la siguiente página web:
<html>
<body onscroll="alert(''body scroll event'')">
<div style=''width:200px;height:200px;overflow:auto'' onscroll="alert(''div scroll event'')">
<div style=''height:400px''>
</div>
</div>
</body>
</html>
Este html crea un div con una barra de desplazamiento. Si mueve la barra de desplazamiento, se activa el evento "onscroll" en el elemento div. Sin embargo, el evento "onscroll" en el cuerpo NO se dispara. Esto es de esperar, ya que el W3C establece que los eventos del elemento onscroll no "burbujean".
Sin embargo, estoy desarrollando un marco web del lado del cliente que necesita saber cada vez que se desplaza una barra de desplazamiento en CUALQUIER elemento de la página. Esto sería fácil de hacer si "onscroll" burbujeara, pero desafortunadamente no es así. ¿Hay alguna otra manera de detectar eventos de onscroll en una página completa? (En este momento me estoy centrando principalmente en Webkit, por lo que una solución específica para Webkit estaría bien ...)
Aquí hay algunas cosas que he intentado: 1. Capturar DOMAttrModified (no parece activarse para mover las barras de desplazamiento). 2. Usar los Observadores DOM (tampoco parece activarse para las barras de desplazamiento) 3. Cambiar el tipo de evento "onscroll" burbujear (parece no ser posible)
Parece que la ÚNICA forma de capturar eventos de onscroll a nivel mundial es adjuntar un evento de onscroll a CADA elemento que pueda desplazarse, lo que es muy feo y va a perjudicar el rendimiento de mi marco.
¿Alguien sabe de una manera mejor?
¡Gracias por adelantado!
La forma más sencilla de detectar todos los eventos de desplazamiento en el navegador moderno sería utilizar "capturar" en lugar de "burbujear" al adjuntar el evento:
window.addEventListener(''scroll'', function(){ code goes here }, true)
Desafortunadamente, como sé, no hay equivalente en el navegador antiguo como <= IE8
Lo siguiente funciona bien cuando desea, por ejemplo, cerrar un cuadro de diálogo después de que se desplace algo en el fondo:
var scrollListener = function(e) {
// TODO: hide dialog
document.removeEventListener(''scroll'', scrollListener, true);
};
document.addEventListener(''scroll'', scrollListener, true);
Tuve el mismo problema.
La forma más fácil, por supuesto, es usar jQuery. Tenga en cuenta que este método podría ralentizar significativamente su página. Además, no tendrá en cuenta ningún elemento nuevo que se agregue después de que el evento esté vinculado.
$("*").scroll(function(e) {
// Handle scroll event
});
En JavaScript de vainilla, puede establecer el valor de uso de useCapture
en true
en su llamada addEventListener
, y se activará en todos los elementos, incluidos los agregados dinámicamente.
document.addEventListener(''scroll'', function(e) {
// Handle scroll event
}, true);
Tenga en cuenta que esto se activará antes de que realmente ocurra el evento de desplazamiento. Como lo entiendo, hay dos fases por las que pasan los eventos. La fase de captura ocurre primero, y comienza desde la raíz de la página (ownerDocument?) Y se desplaza hasta el elemento donde ocurrió el evento. Después de esto viene la fase de burbujeo, que atraviesa desde el elemento hasta la raíz.
Algunas pruebas rápidas también demostraron que esto puede ser lo que hace jQuery (por lo menos para rastrear los desplazamientos en todos los elementos de la página), pero no estoy 100% seguro.
Aquí hay un JSFiddle que muestra el método de vainilla de JavaScript http://jsfiddle.net/0qpq8pcf/