JSFiddle - React, Tailwind, and code Playground

by moob

HTML

<div class="viewport">
    <ul id="slider1">
        <li style="background: lightblue; color: red">1</li>
        <li style="background:gray; color: black;">2</li>
        <li style="background:pink; color: white;">3</li>
    </ul>

</div><button id='b1'>prev</button><button id='b2'>next</button>
<button id='inject'>inject another</button>
<hr />

<div class="viewport">
    <ul id="slider2">
        <li style="background: lightblue; color: red">1</li>
        <li style="background:gray; color: black;">2</li>
        <li style="background:pink; color: white;">3</li>
    </ul>

</div><button id='b3'>prev</button><button id='b4'>next</button>

CSS

.viewport { width: 100%; height: 300px; overflow:hidden; }
ul { list-style: none; margin: 0; padding: 0; position: relative; width: 10000%;  }
ul li { display: block; float: left; width:1%; height: 300px; line-height: 300px; font-size: 30px; text-align: center; }
ul li + li + li {width:0.5%;}
ul li + li + li + li + li + li {width:100px;}

JavaScript

var _Slider = function(args) {
    if(args === undefined){
        throw new Error('Missing required arguments!');
    }
    slider = this;
    slider.id = args.id;
    slider.el = args.el;
    slider.duration = args.duration || 200;
    slider.speed = args.speed || 1000;//pixels per second
    slider.cassette = document.getElementById(args.id);
    slider.slides = slider.cassette.getElementsByTagName('li');
    slider.controls = {
        buttonPrev : document.getElementById(args.prevButtonID),
        buttonNext : document.getElementById(args.nextButtonID)
    }
    slider.index = 0;

    return slider;
}
var computedStyle = function(element){
    return element.currentStyle || window.getComputedStyle(element)
    };
_Slider.prototype.resize = function(){
    widthOfViewport = parseInt(computedStyle(this.cassette.parentNode).width);
    widthOfSlides = 0;
    for(i=0; i<=this.index; i++){
      widthOfSlides+=parseInt(computedStyle(this.slides[i]).width);
    }
    this.cassette.style.left = "-"+(widthOfSlides-widthOfViewport)+"px";
    return;
    };
_Slider.prototype.count = function(){
    return this.slides.length;
    };
_Slider.prototype.next = function(){
      if(this.index+1<this.count()){
            this.index++;
            //this.cassette.style.left = "-"+this.index*100+'%';
          //or we could slide on a per-slide basis
          //everything would have to be in pixels //(which could be a problem on resize unless we use getComputedStyle
          //
          //get the width of the next slide
          //
            currentLeft = parseInt(this.cassette.style.left); widthOfNextSlide=parseInt(computedStyle(this.slides[this.index]).width);
          this.cassette.style.left = currentLeft-widthOfNextSlide+"px";
            
            relativeSpeed = widthOfNextSlide*(this.speed/1000);//
this.cassette.style.transition = 'all '+relativeSpeed+'ms ease-out';
              


        }
    };
_Slider.prototype.prev = function(){
       ...