JSFiddle - React, Tailwind, and code Playground
by danya_postfactum
HTML
<div class="pages">
<div class="page"></div>
<div class="page"></div>
<div class="page"></div>
<div class="page"></div>
</div>
<ul class="menu">
<li>Page 1</li>
<li>Page 2</li>
<li>Page 3</li>
<li>Page 4</li>
</ul>
CSS
html, body{
min-height: 100%;
width: 100%;
margin: 0;
padding: 0;
}
html{
height: 100%;
}
.pages{
height: 100%;
overflow: visible;
position: relative;
top: 0;
transition: top 0.5s;
}
.page{
height: 100%;
min-height: 100vh;
}
.page:nth-child(1){
background: aqua;
}
.page:nth-child(2){
background: greenyellow;
}
.page:nth-child(3){
background: yellow;
}
.page:nth-child(4){
background: blueviolet;
}
.menu{
position: fixed;
display: none;
left: 10px;
top: 50%;
transform: translateY(-50%);
}
.menu li{
cursor: pointer;
}
.menu .active{
color: red;
}
JavaScript
function PageController() {
this.pageContainer = document.querySelector('.pages');
this.pages = this.pageContainer.children;
this.menuContainer = document.querySelector('.menu');
this.menuItems = this.menuContainer.children;
this.current = -1;
this.addEventListeners();
document.body.style.height = '100%';
document.body.style.overflow = 'hidden';
this.menuContainer.style.display = 'block';
document.body.scrollTop = 0;
this.scrollTo(0);
}
PageController.prototype.addEventListeners = function() {
var controller = this;
window.addEventListener('wheel', function(e) {
if (e.deltaY > 0) {
controller.scrollDown();
} else {
controller.scrollUp();
}
});
document.addEventListener('keydown', function(e) {
switch (e.keyCode) {
case 33: // DOM_VK_PAGE_UP
case 38: // DOM_VK_UP
controller.scrollUp();
break;
case 34: // DOM_VK_PAGE_DOWN
case 40: // DOM_VK_DOWN
case 32: // DOM_VK_SPACE
controller.scrollDown();
break;
case 36: // DOM_VK_HOME
controller.scrollTo(0);
break;
case 35: // DOM_VK_END
controller.scrollTo(controller.pages.length - 1);
break;
default:
return;
}
e.preventDefault();
});
for (var i = 0; i < this.menuItems.length; i++) {
this.menuItems[i].setAttribute('data-index', i);
this.menuItems[i].addEventListener('click', function(e) {
e.preventDefault();
controller.scrollTo(this.getAttribute('data-index'));
});
}
};
PageController.prototype.scrollTo = function(index) {
index = Math.min(this.pages.length -1, Math.max(0, index)); // limit to [0;length-1]
if (this.current == index)
return false;
if (this.current != -1)
this.menuItems[this.current].classList.remove('active');
this.current = index;
this.menuItems[this.current].classList.add('active');
this.pageContainer.style.top = (- this.current * 100) + '%';
this
};
PageController.prototype.scrollUp = function() {
return this.scrollTo(this.current - 1);
};
PageController.prototype.scrollDown =...