visit
HTML Boilerplate
First, initiate the simple HTML5 project. For this tutorial, I suggest using this awesome boilerplate called . Select the Classic H5BP and tune the following settings:
.
├── css
│ ├── main.css
│ ├── normalize.css
│ └── normalize.min.css
├── img
├── js
│ ├── vendor
│ │ ├── jquery-1.11.2.min.js
│ │ └── modernizr-2.8.3.min.js
│ └── main.js
└── index.html
Live server
Now it's time to make your HTML project live ⏰Install the using the npm or yarn:
$ npm install -g http-server
# or
$ yarn global add http-server
# -c-1 (disable cache)
$ http-server -c-1
Starting up http-server, serving ./
Available on:
//127.0.0.1:8080
//192.168.8.10:8080
//192.168.250.1:8080
Hit CTRL-C to stop the server
Go to in your browser and you should see the Hello world! This is HTML5 Boilerplate.
Open the index.html and find the following line
<p>Hello world! This is HTML5 Boilerplate.</p>
<div id="section1" class="section">
<span>1. Viewport height section</span>
</div>
<div id="section2" class="section">
<span>2. Long section</span>
</div>
<div id="section3" class="section">
<span>3. Short section</span>
</div>
<div id="section4" class="section">
<span>4. Viewport height section</span>
</div>
Now in css/main.css find the block:
/* ==========================================================================
Author's custom styles
========================================================================== */
/* We center the text, make the text color
white and increase the font size */
.section {
color: white;
display: flex;
align-items: center;
justify-content: center;
font-weight: 800;
font-size: 120%;
font-weight: 800;
position: relative;
}
/* The height of the first section
will be equal to the viewport height */
#section1 {
height: 100vh;
background: #6699cc;
}
/* The height of the second section
will be 150% of the viewport height */
#section2 {
height: 150vh;
background: #ff8c42;
}
/* 60% height */
#section3 {
height: 60vh;
background: #ff3c38;
}
/* 100% (equal again) */
#section4 {
height: 100vh;
background: #a23e48;
}
All the magic goes to the js/main.js.
The basic idea is to collect all the sections and animate the scroll between their offsets on the mouse wheel event. So first, using the JQuery we collect all sections by .section class name, and define the wheel event handler.
// Collecting the sections
var $sections = $(".section");
// Define wheel event handler
document.addEventListener("wheel", function(event) {
}, { passive: false });
// We set passive to false because in the handler we need to prevent the default mouse wheel behavior
// Collecting the sections
var $sections = $(".section");
// Define wheel event handler
document.addEventListener(
"wheel",
function(event) {
// Get the mouse wheel spin direction
var direction = event.deltaY;
if (direction > 0) {
// Go to next
} else {
// Go to previous
}
},
{ passive: false }
);
// We set passive to false, because in the handler we need to prevent the default mouse wheel behavior
// Collecting the sections
var $sections = $(".section");
// Variable to hold the current section index
var currentIndex = 0;
// Define wheel event handler
document.addEventListener(
"wheel",
function(event) {
// Get the mouse wheel spin direction
var direction = event.deltaY;
if (direction > 0) {
// Go to next
// Increase the section pointer
currentIndex++;
// Get the next section
var $nextSection = $($sections[currentIndex]);
} else {
// Go to prev
// Decrease the section pointer
currentIndex--;
// Get the previous section
var $previousSection = $($sections[currentIndex]);
}
},
{ passive: false }
);
// We set passive to false, because in the handler we need to prevent the default mouse wheel behavior
// Collecting the sections
var $sections = $(".section");
// Variable to hold the current section index
var currentIndex = 0;
// Define wheel event handler
document.addEventListener(
"wheel",
function(event) {
// Get the mouse wheel spin direction
var direction = event.deltaY;
if (direction > 0) {
// If next index is greater than sections count, do nothing
if (currentIndex + 1 >= $sections.length) return;
// Go to next
// Increase the section pointer
currentIndex++;
// Get the next section
var $nextSection = $($sections[currentIndex]);
} else {
// If previous index is negative, do nothing
if (currentIndex - 1 < 0) return;
// Go to prev
// Decrease the section pointer
currentIndex--;
// Get the previous section
var $previousSection = $($sections[currentIndex]);
}
},
{ passive: false }
);
// We set passive to false, because in the handler we need to prevent the default mouse wheel behavior
// Collecting the sections
var $sections = $(".section");
// Variable to hold the current section index
var currentIndex = 0;
// Define wheel event handler
document.addEventListener(
"wheel",
function(event) {
// Get the mouse wheel spin direction
var direction = event.deltaY;
if (direction > 0) {
// If next index is greater than sections count, do nothing
if (currentIndex + 1 >= $sections.length) return;
// Go to next
// Increase the section pointer
currentIndex++;
// Get the next section
var $nextSection = $($sections[currentIndex]);
// Get the next section offset
var offsetTop = $nextSection.offset().top;
// Prevent the default mouse wheel behaviour
event.preventDefault();
// Animate scroll
$("html, body").animate({ scrollTop: offsetTop }, 1000);
} else {
// If previous index is negative, do nothing
if (currentIndex - 1 < 0) return;
// Go to prev
// Decrease the section pointer
currentIndex--;
// Get the previous section
var $previousSection = $($sections[currentIndex]);
// Get the previous section offset
var offsetTop = $previousSection.offset().top;
// Prevent the default mouse wheel behaviour
event.preventDefault();
// Animate scroll
$("html, body").animate({ scrollTop: offsetTop }, 1000);
}
},
{ passive: false }
);
// We set passive to false, because in the handler we need to prevent the default mouse wheel behavior
Define the variable which holds the state of the animation. Set variable to true when animation starts, and - false when animation finished. In the event handler, if we detected that animation is in progress, we just prevent the default mouse wheel behavior.
// Collecting the sections
var $sections = $(".section");
// Variable to hold the current section index
var currentIndex = 0;
// Variable to hold the animation state
var isAnimating = false;
// Define the animation finish callback
var stopAnimation = function() {
// We add the 300 ms timeout to debounce the mouse wheel event
setTimeout(function() {
// Set the animation state to false
isAnimating = false;
}, 300);
};
// Define wheel event handler
document.addEventListener(
"wheel",
function(event) {
// If animation is in progress
if (isAnimating) {
// Just prevent the default mouse wheel behaviour
event.preventDefault();
return;
}
// Get the mouse wheel spin direction
var direction = event.deltaY;
if (direction > 0) {
// If next index is greater than sections count, do nothing
if (currentIndex + 1 >= $sections.length) return;
// Go to next
// Increase the section pointer
currentIndex++;
// Get the next section
var $nextSection = $($sections[currentIndex]);
// Get the next section offset
var offsetTop = $nextSection.offset().top;
// Prevent the default mouse wheel behaviour
event.preventDefault();
// Set the animation state to true
isAnimating = true;
// Animate scroll
$("html, body").animate({ scrollTop: offsetTop }, 1000, stopAnimation);
} else {
// If previous index is negative, do nothing
if (currentIndex - 1 < 0) return;
// Go to prev
// Decrease the section pointer
currentIndex--;
// Get the previous section
var $previousSection = $($sections[currentIndex]);
// Get the previous section offset
var offsetTop = $previousSection.offset().top;
// Prevent the default mouse wheel behaviour
event.preventDefault();
// Set the animation state to true
isAnimating = true;
// Animate scroll
$("html, body").animate({ scrollTop: offsetTop }, 1000, stopAnimation);
}
},
{ passive: false }
);
// We set passive to false, because in the handler we need to prevent the default mouse wheel behavior
I could say that is done. But I don't wanna lie. If you check our slider in the browser you will see that there no struggle anymore. But we have the last thing to do. Look at the second section (2. Long section). You can't scroll to the end of this section, because on the mouse wheel spin, section 3 (3. Short section) comes in to view.
To fix this, we should prevent the slide to the next section if we don't reach the current section bottom and vice versa, we should prevent the slide to the previous section if we don't reach the current section top.Define the two functions// Function returns true if DOM element bottom is reached
var bottomIsReached = function($elem) {
var rect = $elem[0].getBoundingClientRect();
return rect.bottom <= $(window).height();
};
// Function returns true if DOM element top is reached
var topIsReached = function($elem) {
var rect = $elem[0].getBoundingClientRect();
return rect.top >= 0;
};
// Collecting the sections
var $sections = $(".section");
// Variable to hold the current section index
var currentIndex = 0;
// Variable to hold the animation state
var isAnimating = false;
// Define the animation finish callback
var stopAnimation = function() {
// We add the 300 ms timeout to debounce the mouse wheel event
setTimeout(function() {
// Set the animation state to false
isAnimating = false;
}, 300);
};
// Function returns true if DOM element bottom is reached
var bottomIsReached = function($elem) {
var rect = $elem[0].getBoundingClientRect();
return rect.bottom <= $(window).height();
};
// Function returns true if DOM element top is reached
var topIsReached = function($elem) {
var rect = $elem[0].getBoundingClientRect();
return rect.top >= 0;
};
// Define wheel event handler
document.addEventListener(
"wheel",
function(event) {
// If animation is in progress
if (isAnimating) {
// Just prevent the default mouse wheel behaviour
event.preventDefault();
return;
}
// Get the current section
var $currentSection = $($sections[currentIndex]);
// Get the mouse wheel spin direction
var direction = event.deltaY;
if (direction > 0) {
// If next index is greater than sections count, do nothing
if (currentIndex + 1 >= $sections.length) return;
// If bottom is not reached allow the default behaviour
if (!bottomIsReached($currentSection)) return;
// Go to next
// Increase the section pointer
currentIndex++;
// Get the next section
var $nextSection = $($sections[currentIndex]);
// Get the next section offset
var offsetTop = $nextSection.offset().top;
// Prevent the default mouse wheel behaviour
event.preventDefault();
// Set the animation state to true
isAnimating = true;
// Animate scroll
$("html, body").animate({ scrollTop: offsetTop }, 1000, stopAnimation);
} else {
// If previous index is negative, do nothing
if (currentIndex - 1 < 0) return;
// If top is not reached allow the default behaviour
if (!topIsReached($currentSection)) return;
// Go to prev
// Decrease the section pointer
currentIndex--;
// Get the previous section
var $previousSection = $($sections[currentIndex]);
// Get the previous section offset
var offsetTop = $previousSection.offset().top;
// Prevent the default mouse wheel behaviour
event.preventDefault();
// Set the animation state to true
isAnimating = true;
// Animate scroll
$("html, body").animate({ scrollTop: offsetTop }, 1000, stopAnimation);
}
},
{ passive: false }
);
// We set passive to false, because in the handler we need to prevent the default mouse wheel behavior
🌟 Follow on
🌟 Connect on