JSFiddle - React, Tailwind, and code Playground

by someprimetime

HTML

<div class="spacing1k"></div>
<div class="wrap">
   <div class="js-sticky-container">
      <div class="product_menu left">
         <ul id="js-product-menu">
            <li>Product 1</li>
            <li>Product 2</li>
            <li>Product 3</li>
            <li>Product 4</li>
            <li>Product 5</li>
            <li>Product 6</li>
            <li>Product 7</li>
            <li>Product 8</li>
            <li>Product 9</li>
         </ul>
      </div>
   </div>
   <div class="right">
      <div id="js-current-products">
         <div class="js-current-product border">
            <img src="http://i.imgur.com/6iLRR.png" />
         </div>
         <div class="spacing1k"></div>
         <div class="js-current-product border">
            <img src="http://i.imgur.com/zO4yH.png" />
         </div>
         <div class="spacing1k"></div>
         <div class="js-current-product border">
            <img src="http://i.imgur.com/yAjFb.png" />
         </div>
          
         <div class="spacing1k"></div>
         <div class="js-current-product border">
            <img src="http://i.imgur.com/yAjFb.png" />
         </div>
         <div class="spacing1k"></div>
         <div class="js-current-product border">
            <img src="http://i.imgur.com/yAjFb.png" />
         </div>
         <div class="spacing1k"></div>
         <div class="js-current-product border">
            <img src="http://i.imgur.com/yAjFb.png" />
         </div>
         <div class="spacing1k"></div>
         <div class="js-current-product border">
            <img src="http://i.imgur.com/yAjFb.png" />
         </div>
         <div class="spacing1k"></div>
         <div class="js-current-product border">
            <img src="http://i.imgur.com/yAjFb.png" />
         </div>
         <div class="spacing1k"></div>
         <div class="js-current-product border">
            <img src="http://i.imgur.com/yAjFb.png" />
         </div>
      </div>
   </div>
   <div class="spacing2k"></div>
  ...

CSS

.wrap {
    width: 1000px;
}
.js-sticky-wrap {
    background-color: #ccc;
}
.js-drop-shadow {
    border-bottom: 2px solid #000;
}

.js-sticky-fixed {
    position: fixed;
    top: 0;
    z-index: 200;
}
.spacing2k {
    height: 2000px;
}
.spacing1k {
    height: 1000px;
}
.product_menu {
    width: 200px;
}
li {
    display: block;
    background-color: white;
}
.selected {
    color: #fff;
    background-color: black;
}
.left {
    float: left;
}
.right {
    float: right;
}
.border { 
    border: 1px solid #ccc;
}

JavaScript

$(function() {
    // Our menu to clone
    var stickyDiv = $('.js-sticky-container');
    // Class with fixed positioning
    var posFixed = 'js-sticky-fixed';
    // Product menu's offset from top window
    var menuTop = stickyDiv.offset().top;
    // Clone the product menu, and add the fixed class
    var menuClone = stickyDiv.clone(true).addClass(posFixed);

    $('#js-product-menu li').each(function(index, value) {
        var newIndex = index + 1;
        $(this).attr('id', 'js-product-' + newIndex);
    });

    $('#js-current-products .js-current-product').each(function(index, value) {
        var newIndex = index + 1;
        $(this).attr('id', 'js-current-product-' + newIndex);
    });

    var productPosition = function() {
        $('.js-current-product').each(function(index, value) {
            // start at a base index of 1 instead of 0
            var newIndex = index + 1;
            // Get offset (minus a 500px buffer) of the product image
            var currentProduct = $(this).offset().top - 500;
            if (scrollY > currentProduct) {
                $('#js-product-menu li').removeClass('selected');
                $('#js-product-' + newIndex).addClass('selected');
            }
        });
    };

    // This basically clones the div surrounded by `.js-sticky-container` and adds a 
    // class with a fixed position on it to "stick" 
    var stickyContainer = function(stickyDiv, posFix, clonedWidth) {
        // Use the original container width
        if (clonedWidth === undefined) {
            clonedWidth = $(stickyDiv).width();
        }

        $(window).bind('scroll', function() {

            // Check position of the product image and add the class to the nav menu
            // if the corresponding image fits the product name
            productPosition();

            // What the current px is from vertical scroll
            var scrollY = window.pageYOffset;

            // They scrolled more than the original offset
        ...