JSFiddle - React, Tailwind, and code Playground

by bgmort

HTML

<p>asdf</p>
<p>asdf</p>
<p>asdf</p>
<p>asdf</p>
<p>asdf</p>
<p>asdf</p>
<p>asdf</p>
<p>asdf</p>
<p>asdf</p>
<p>asdf</p>
<p>asdf</p>
<p>asdf</p>
<p>asdf</p>
<p>asdf</p>
<p>asdf</p>
<p>asdf</p>
<p>asdf</p>
<p>asdf</p>
<p>asdf</p>
<p>asdf</p>
<p>asdf</p>
<p>asdf</p>
<p>asdf</p>
<p>asdf</p>
<p>asdf</p>
<p>asdf</p>
<p>asdf</p>
<p>asdf</p>
<p>asdf</p>
<p>asdf</p>
<p>asdf</p>
<p>asdf</p>
<p>asdf</p>
<p>3...</p>
<p>asdf</p>
<p>asdf</p>
<p>2...</p>
<p>asdf</p>
<p>asdf</p>
<p>1...</p>
<report style="display: none">
	<progress></progress>
	<p class="log"></p>
</report>

CSS

html, body {
}
report {
	position: fixed;
	bottom: 0px;
	height: 70px;
	width: 200px;
	left: 50%;
	margin-left: -100px;
	text-align: center;
}

JavaScript

function ScrollPastEndGesture(opts) {
	var _this = this;
	opts = opts || {};
	opts.distance = opts.distance || 2500;
	opts.within = opts.within || 1000;
	opts.onProgress = opts.onProgress || null;
	opts.onComplete = opts.onComplete || null;	

	var scrollSum = 0, scrolling = false, atEnd = false, scrollingTimeout = null, progressTimeout = null, paused = false, prevDeltaY = 0, mightStillBeMomentumScrolling = false, scrollDirection = 1;
   
	window.addEventListener('scroll', function(e) {
		scrolling = true;
		atEnd = 0;

		if (scrollingTimeout) {
			clearTimeout(scrollingTimeout);
			scrollingTimeout = null;
		}
		else {
			console.log('scrolling');
		}
		//scrolling stopped when there have been no scroll events for 100ms
		scrollingTimeout = setTimeout(scrollingStopped, 100);
	});

	window.addEventListener('wheel', function(e) {
		if (paused) return;
		
		/*
		if (!scrolling && scrollingTimeout) {
			//waiting for the wheel events to finish
			clearTimeout(scrollingTimeout);
			scrollingTimeout = setTimeout(function() {
				scrollingTimeout = null;
				console.log('scrolling really stopped');
			}, 100);
			return;
		}
		*/
		if (scrolling) {
			prevDeltaY = e.deltaY;
		}
		
		if (!scrolling && e.deltaY * scrollDirection > 0) {
			if (mightStillBeMomentumScrolling) {
				//when the delta value goes up, we know it's a new scroll movement
				if (e.deltaY * scrollDirection > prevDeltaY * scrollDirection) {
					mightStillBeMomentumScrolling = false;
					prevDeltaY = 0;
					++atEnd;
				}
				else {
					prevDeltaY = e.deltaY;
				}
			}
			else {
				++atEnd;
			}
		}
		else if (e.deltaY * scrollDirection < 0) {
			scrollSum = 0;
			scrollDirection *= -1;
			console.log('switching scrollDirection', scrollDirection, e.deltaY)
		}			
		
		if (atEnd >= 3) {
			scrollSum += e.deltaY * scrollDirection;
			if (scrollSum > opts.distance) {
				//reset
				scrollSum = 0;
				atEnd = 0;
				paused = true;
				clearTimeout(progressTimeout);

				setTimeout(function()...