overpull

by Nic Fontaine

HTML

<div id='overpull'></div>
<span id='overpull-msg'>refreshing...</span>
<p>Scroll to bottom, then click-drag up</p>
<p>Scroll to bottom, then click-drag up</p>
<p>Scroll to bottom, then click-drag up</p>
<p>Scroll to bottom, then click-drag up</p>
<p>Scroll to bottom, then click-drag up</p>
<p>Scroll to bottom, then click-drag up</p>
<p>Scroll to bottom, then click-drag up</p>
<p>Scroll to bottom, then click-drag up</p>
<p>Scroll to bottom, then click-drag up</p>
<p>Scroll to bottom, then click-drag up</p>
<p>Scroll to bottom, then click-drag up</p>
<p>Scroll to bottom, then click-drag up</p>
<p>Scroll to bottom, then click-drag up</p>
<p>Scroll to bottom, then click-drag up</p>
<p>Scroll to bottom, then click-drag up</p>
<p>Scroll to bottom, then click-drag up</p>
<p>Scroll to bottom, then click-drag up</p>
<p>Scroll to bottom, then click-drag up</p>
<p>Scroll to bottom, then click-drag up</p>
<p>Scroll to bottom, then click-drag up</p>
<p>Scroll to bottom, then click-drag up</p>
<p>Scroll to bottom, then click-drag up</p>
<p>Scroll to bottom, then click-drag up</p>
<p>Scroll to bottom, then click-drag up</p>
<p>Scroll to bottom, then click-drag up</p>
<p id='demo'></p>

CSS

html {
  margin: 0;
}

p {
  margin-bottom: 30px;
}

#demo {
  position: fixed;
  right: 0;
  top: 0;
}

#overpull {
  background: teal;
  position: fixed;
  bottom: 0;
  height: 1px;
  right: 0;
  left: 0;
  margin: 0 auto;
  color: #fff;
  transition: max-height 2s ease-out;
  height: 100%;
  top: 100%;
  opacity: 0.3;
}

#overpull-msg {
  position: fixed;
  bottom: 0;
  transform: translateY(0);
  right: 0; left: 0;
  margin: 0 auto;
  opacity: 0;
  transition: all 0.3s;
  text-align: center;
  transform: translate(0,0);
  color: #fff;
  z-index: 3;
}

#overpull-msg.show {
  opacity: 1;
  transform: translateY(-10px);
}

JavaScript

var pull = document.getElementById('overpull');
var msg = document.getElementById('overpull-msg');
var height = pull.clientHeight;
var cursorClickOffset = 0;
var wHeight = window.outerHeight;

var maxH = 120;

// TOGGLE DISABLE FOR TOUCHEND
var pullToggle = true;
// HEIGHT SUCCES FLAG FOR TOUCHEND
var pullSuccess = false;

var touchEvDown = 'ontouchstart' in window ? 'touchstart' : 'mousedown';
var touchEvUp = 'ontouchend' in window ? 'touchend' : 'mouseup';
var touchEvMove = 'ontouchmove' in window ? 'touchmove' : 'mousemove';
// FLAG TO SWAP INPUT'S Y POS
var mobile = 'ontouchstart' in window ? true : false;

// if (mobile) {
window.onscroll = function(ev) {
	// SCROLLED TO BOTTOM, ENABLE
	if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
    document.addEventListener(touchEvDown, pullOnHandler);
		document.addEventListener(touchEvUp, pullOffHandler);
	}
  // DISABLE/REMOVE EVENTS
  else {
  	pullToggle = false;
  	document.removeEventListener(touchEvDown, pullOnHandler);
  	document.removeEventListener(touchEvUp, pullOffHandler);
  }
};
// }

// TAKE INPUT, CALCULATE OFFSET & ADD pullHeight EventListener
var pullOnHandler = function(e) {
  pullToggle = true;
  pull.style.transition = 'none';
	document.addEventListener(touchEvMove,function foo(e) {
  	pullHeight(e,pullToggle);
  });
  cursorClickOffset = mobile ? wHeight-(e.targetTouches[0].pageY) : wHeight-(e.clientY);
};

// INPUT RELEASE
var pullOffHandler = function(e) {
	pullToggle = false;
	document.removeEventListener(touchEvMove, function(e) {
  	pullHeight(e,pullToggle);
  });
  
  pull.style.transition = 'transform 0.25s ease-in';
  pull.style.transform = 'translateY(0)';
  
  if (pullSuccess) {
  	pull.style.transform = 'translateY(-40px)';
    cursorClickOffset = 0;
    
    // PUT STATE CHANGE FUNCTION HERE TO TRIGGER ON RELEASE
    
  }
};

function pullHeight(inp,trueFalse) {
	if (trueFalse) {
  	// CALC FROM DOC HEIGHT, INITIAL CLICK POS, & CLICK MOVE
  	var...