JSFiddle - React, Tailwind, and code Playground

by SpaceDog

HTML

<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.5.2/underscore-min.js"></script>
 <div class="page">
     <div class="page-contents"></div>
 </div>
 <div class="page">
     <div class="page-contents"></div>
 </div>
 <div class="page">
     <div class="page-contents"></div>
 </div>
 <div class="page">
     <div class="page-contents"></div>
 </div>

CSS

.page{
    height: 750px;
    width: 100%;
    margin: 10px 0;
    background: gray;
}

.page-contents{
    height: 100%;
    width: 100%;
}

JavaScript

var nosnap = false;

var snap = _.debounce(function(event){
    // Don't snap if already animating ...
    if (nosnap) { nosnap = false; console.log(event); return; } 
    nosnap = true;
    //Check each page view            
    $.each($('.page-contents'), function(index, element){
        
        //If the page view is 70% of the screen and we are allowed to snap, snap into view
        if($(element).isNearScreen(0.7)){
            
            $('html,body').animate({
                scrollTop: $(element).offset().top
            }, 300);
        }
    });  
}, 500);

//Returns "true" if element is percent visible within the viewport
$.fn.isNearScreen = function(percent){
    
    var offset = 1 - percent;
    
    var win = $(window);
     
    var viewport = {
        top : win.scrollTop()
    };

    viewport.bottom = viewport.top + win.height();
     
    var bounds = this.offset();
    bounds.bottom = bounds.top + this.outerHeight();
    bounds.top = bounds.top;

    //If the element is visible
    if(!(viewport.bottom < bounds.top || viewport.top > bounds.bottom)){
    	
        //Get the percentage of the element that's visible
        var percentage = (viewport.bottom - bounds.top) / this.height();
        
        //If it's greater than percent, but less than 1 + (1 - percent), return true;
    	return (percentage > (1 - offset) && percentage < (1 + offset));
    }
    return false;
     
};

$(window).on('scroll', snap);