JSFiddle - React, Tailwind, and code Playground

by ruisoftware

HTML

<div class="btnWrap">
      <p>
          <a href="#arrow" class="scrollUp">Scroll Up</a>
          <a href="#arrow" class="scrollDown">Scroll Down</a><br />
          
          <a href="#arrow" class="scrollUpBig">Scroll Up (big)</a>
          <a href="#arrow" class="scrollDownBig">Scroll Down (big)</a>
          
          <a href="#arrow" class="scrollUpBigPlus">Scroll Up (big+)</a>
          <a href="#arrow" class="scrollDownBigPlus">Scroll Down (big+)</a>
      </p>
  </div>
  depending on the item's height, the lisbox will expand or shrink

  <ul id="scroller">
      <li class="current"><span>/</span><a href="#article1">News Article Title</a></li>
      <li><span>/</span><a href="#article2">News Article Title 2</a></li>
      <li><span>/</span><a href="#article3">News Article Title 3</a></li>
      <li><span>/</span><a href="#article4">News Article Title 4</a></li>
      <li><span>/</span><a href="#article5">News Article Title 5</a></li>
  </ul>

CSS

#scroller {
    border: 1px black solid;
    overflow: hidden;
    height: auto;
}

li {
    background-color: #ddb;
    margin: 5px;
    padding: 5px;
}

.btnWrap a {
    display: inline-block;
    width: 200px;
    border: 1px red solid;
    margin: 4px;
}

JavaScript

var speed = 300, //ms
    $scroller = $("#scroller"),
    items = {
        createItem: function(text, url) {
            return $('<li>').append($('<span>').append('/')).append($('<a>').append(text).attr('href', url));
        },
        getFirst: function() {
            return $("li", $scroller).first();
        },
        getSecond: function() {
            return $("li", $scroller).eq(1);
        },
        getSecondFromLast: function() {
            return $("li", $scroller).eq(-2);
        },
        getLast: function() {
            return $("li", $scroller).last();
        },
        init: function() {
            this.getFirst().css('margin-top', 15);
            this.getLast().css('margin-bottom', 15);
        }
    },        
    
    smoothAddOnTop = function (text, url) {
        var $firstItem = items.createItem(text, url),
            heightScroller = $scroller.height();
        $scroller.prepend($firstItem);
        var deltaHeight = $firstItem.outerHeight() - items.getLast().outerHeight(),
            heightItem = $firstItem.outerHeight(true);
        // hide the new li on top then move it down
        $scroller.height(heightScroller).scrollTop(heightItem);
        items.getSecond().animate({
            'margin-top': 0
        }, {
            duration: speed,
            complete: function() {
                items.getSecondFromLast().animate({
                    'margin-bottom': heightItem
                }, speed);
                
                $firstItem.animate({
                    'margin-top': heightItem
                }, speed);

                $scroller.animate({'height': '+=' + deltaHeight}, speed);
                
                items.getLast().animate({
                    'margin-top': heightItem
                }, {
                    duration: speed, 
                    complete: function() {
                        items.getLast().remove();
                        items.init();
                    }
               ...