Saludos,
- A mi me funciona bien:
- Solo tienes que considerar que el margen es la distancia máxima que puede haber antes de bajar el Scroll al máximo, es decir, puede ser el tamaño en pixeles de tu pie de página.
- El margen debería de ser 0, pero no es así debido a los cálculos previos [ $(document).height() - $(window).scrollTop() - $(window).height() ] lo cual devuelve un decimal muy cercano a cero pero no cero.
- Puedes tener problemas en el funcionamiento debido a que usas alert(), ya que este toma el foco y deja desconcertado al scroll, este scroll podría seguir moviéndose o quedar en stand by. Además debes considerar de que el evento scroll se realiza cuando el scroll se mueve/cambia, y esto sucede cuando se cambia de tamaño la ventana, el usuario lo mueve, se hace zoom, etc. Por esto es que se te ejecuta varias veces si el scroll se encuentra tocando el "margen" y se produce alguno de estos eventos.
La explicación del alert no es correcta. El scroll no se vuelve loco tras un alert. Se ejecuta múltiples veces por como está implementada la función en Jquery, no porque el cambio de foco afecte de ninguna forma al scroll o se vuelva a detectar un evento debido al cambio de foco. Es importante aclararlo porque se puede registrar prácticamente cualquier evento, cambio de foco incluido.
La función del scroll en Jquery no es más que un bindeo de un handler a un evento en javascript. Cada vez que el scroll se mueve se hace una llamada al handler del evento.
Puedes desbindear el handler justo antes del alert o el prompt y el trigger del evento no hace nada ya que el handler esta desbindeado de la funcion tras el evento y lo vuelves a bindear con un click del mouse, una pulsación del teclado, un movimiento en la rueda del ratón o un timer para que no haga trigger al mostrar el alert entre otras opciones.
https://plainjs.com/javascript/events/binding-and-unbinding-of-event-handlers-12/Puedes usar .removeEventListener('evento', nombreDelHandler)
Otra opción es bindear el handler solo al scroll principal como lo harías para un contenedor en html y no a todo el documento, por lo que así no detectaría nuevos objetos ni eventos relacionados con otros scrolls en la página. Ya que tal y como está, si metes 20 scrolls y el tamaño coincide o excede el ejemplo para por ejemplo mostrar ejemplos de un código, imagenes desplazables, etc todos te van a hacer trigger, incluyendo los alert y prompt y no solo al llegar al pie de página como se requiere.
Tema a parte, el performance se reduce mucho ya que la llamada al handler se hace continuamente al ir desplazando el scroll independientemente de que haga trigger o no del alert, por lo que lo más lógico es ponerle un delay tras detectar cada evento.
Lo haces de forma muy simple añadiendo un booleano para que no se llame a la función scroll tras ser comprobada, y al pasar X milisegundos vuelves a cambiar el valor del booleano para que se vuelva a comprobar.
Usando vanilla:
https://developer.mozilla.org/es/docs/Web/API/Document/scroll_eventUsando Jquery:
var scrollEnMovimiento = false;
$(window).scroll(esperaScroll()
{
scrollEnMovimiento = true;
});
setInterval(esperaScroll()
{
if (scrollEnMovimiento)
{
scrollEnMovimiento = false;
//Lo que quieras hacer.
}
}, 200 );
200 es el tiempo de delay en milisegundos.
En la mayoría de navegadores también puedes usar capture con pasive y active para settear true y false.