JSFiddle - React, Tailwind, and code Playground
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/4.0.7/rx.all.min.js"></script>
<div id="main">
<button class="left">Prev</button>
<div class="container">
<img class="hide" src="http://lorempixel.com/g/150/150/" alt="">
<img class="hide" src="http://lorempixel.com/g/150/150/?foo=bar1451561" alt="">
<img class="hide" src="http://lorempixel.com/g/150/150/?foo=bar2757547" alt="">
<img class="hide" src="http://lorempixel.com/g/150/150/?foo=bar3778885" alt="">
<img class="hide" src="http://lorempixel.com/g/150/150/?foo=bar4787888" alt="">
<img class="hide" src="http://lorempixel.com/g/150/150/?foo=bar5788111" alt="">
<img class="hide" src="http://lorempixel.com/g/150/150/?foo=bar6798455" alt="">
<img class="hide" src="http://lorempixel.com/g/150/150/?foo=bar7123582" alt="">
</div>
<button class="right">Next</button>
</div>
<p>Press left or right</p>
CSS
#main {
text-align: center;
margin-top: 25px;
display: flex;
justify-content: space-between;
align-items:center;
}
.container {
flex: 3;
}
img {
border-radius:10px;
}
.hide {
display: none;
}
.left,
.right {
background-color: #040404;
color: white;
padding: 10px;
border: none;
border-radius: 6px 4px;
margin:10px;
}
p{
text-align:center;
margin-top:25px;
}
Babel + JSX
var images = [...document.querySelectorAll("img")]; // document.querySelector return a nodeList, nodeList does not support array-ish things like filter, forEach
var maxLength = images.length - 2;
var leftArrow = document.querySelector(".left");
var rightArrow = document.querySelector(".right");
var rightClickSource = Rx.Observable
.fromEvent(rightArrow, "click")
.map(e => 1);
var leftClickSource = Rx.Observable
.fromEvent(leftArrow, "click")
.map(e => -1);
var arrowKeysSource = Rx.Observable
.fromEvent(document, "keyup")
.filter(e => e.keyCode === 37 || e.keyCode === 39)
.map(e => (e.keyCode === 39 ? 1 : -1));
var source = Rx.Observable
.merge(rightClickSource, leftClickSource, arrowKeysSource)
.scan((acc, currentValue) => {
var nextValue = acc + currentValue;
nextValue = (nextValue < maxLength ? nextValue : maxLength - 1);
nextValue = (nextValue > -1 ? nextValue : 0);
return nextValue;
}, 0).startWith(0);
source.subscribe((next) => {
changeImages(next);
showArrows(next);
});
function changeImages(index) {
images.filter(i => !i.classList.contains("hide")).forEach(addHide);
removeHide(images[index]);
removeHide(images[index + 1]);
removeHide(images[index + 2]);
}
function showArrows(index) {
showArrow(leftArrow, (index > 0));
showArrow(rightArrow, (index < maxLength - 1));
}
function showArrow(arrow, condition){
if(condition){
removeHide(arrow);
}else{
addHide(arrow);
}
}
function addHide(elem) {
elem.classList.add("hide");
}
function removeHide(elem) {
elem.classList.remove("hide");
}