INTRODUCTION
POWER OF ENDLESS CONTENTS
Welcome to a step-by-step tutorial on how to create an infinite page scroll with vanilla Javascript. If you have been following up with social media – Facebook, Twitter, Google Plus, Instagram, etc… Then you should not be a stranger to that “scroll down to load more contents” interface.
Yep, that is an interesting (and lazy) way to serve contents to your readers without having to click on an “ugly next page button”. That is exactly what we will walk through in this guide, to create your own infinte scroll with vanilla Javascript. Read on!
I have included a zip file with all the source code at the end of this tutorial, so you don’t have to copy-paste everything… Or if you just want to dive straight in.
Related Articles
CONFESSION
AN HONEST DISCLOSURE
Quick, hide your wallets! I am an affiliate partner of Google, eBay, Adobe, Bluehost, Clickbank, and more. There are affiliate links and advertisements throughout this website. Whenever you buy things from the evil links that I recommend, I will make a commission. Nah. These are just things to keep the blog going, and allows me to give more good stuff to you guys - for free. So thank you if you decide to pick up my recommendations!
NAVIGATION
TABLE OF CONTENTS
Step 0 | Step 1 | Step 2 |
Step 3 | Extra | Closing |
STEP 0
SAMPLE DATABASE
Before we go into the actual code, let us start with the sample database that we will be working within this example.
THE SQL AND SAMPLE DATA
CREATE TABLE `contents` (
`id` int(11) NOT NULL,
`title` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `contents` (`id`, `title`) VALUES
(19, 'Blue Winter'),
(9, 'Bridge of Servants'),
(49, 'Darkest Dream'),
(48, 'Girl in the End'),
(39, 'Heat of Destruction'),
(36, 'Hustler in the Son'),
(24, 'Hustler in the Twins'),
(21, 'Legend of Flowers'),
(25, 'Lost Beginning'),
(6, 'Man in the Game'),
(3, 'Memory of Flames'),
(30, 'Pirates in the Female'),
(7, 'Rough Winter'),
(31, 'Rough Years'),
(33, 'Secret of Vision'),
(37, 'Silent Valley'),
(1, 'Sleeping Beginning'),
(10, 'The Angel\'s Heart'),
(20, 'The Bloody Kiss'),
(44, 'The Bloody Past'),
(26, 'The Blue Flight'),
(38, 'The Broken Butterfly'),
(34, 'The Door\'s Prophecy'),
(17, 'The Dream of the Pleasure'),
(5, 'The Dreamer of the Souls'),
(29, 'The Edge of the Words'),
(46, 'The Flame\'s Husband'),
(11, 'The Flames of the Someone'),
(35, 'The Flight of the Man'),
(8, 'The Growing Princess'),
(22, 'The Husband\'s Bridge'),
(40, 'The Name\'s Time'),
(32, 'The Next Twilight'),
(28, 'The Prophecy\'s Streams'),
(14, 'The Purple Vision'),
(23, 'The Return of the Serpent'),
(50, 'The Silky Beginning'),
(16, 'The Someone\'s Wizard'),
(4, 'The Stars\'s Light'),
(47, 'The Vision of the Flowers'),
(2, 'The What Dream'),
(41, 'The Wizard of the Sorcerer'),
(45, 'Thoughts of Sorcerer'),
(13, 'Twinkling Door'),
(12, 'Waves in the Secrets'),
(43, 'Whispering Dreams'),
(15, 'Window of Snake'),
(18, 'Wings in the Sword'),
(27, 'Witch of Word'),
(42, 'Words in the History');
ALTER TABLE `contents`
ADD PRIMARY KEY (`id`),
ADD KEY `title` (`title`);
ALTER TABLE `contents`
MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=51;
COMMIT;
Nothing much, this sample table only has 2 fields –
- The ID as the primary key.
- The title of the content.
That’s it, if you wish to use your own contents with this example, please feel free to do so… Although I will recommend going through this tutorial one round first before implementing any changes.
STEP 1
THE HTML AND CSS
Let us start with the easiest part of the tutorial – The HTML and CSS. These are just some simple interface, and should not cause you any brain damage.
THE HTML
Endless scroll MY AWESOME SITE
Now loading...
This HTML should be very straightforward, and actually, the header and footer are not relevant. The only 2 important parts are:
- The
page-content
is where the contents will be loaded into via AJAX. - The
page-load
is a simple “now loading” message that will show whenever content is being fetched from the server. Feel free to use your own AJAX spinner image if you want.
THE CSS
hmtl, body{
font-family: arial;
}
#page-header{
padding: 10px;
background: #ffd1d1;
}
#page-content{
padding: 10px;
background: #dffcd1;
}
.docket{
width: 300px;
padding: 10px;
background: #fff9e2;
border: 1px solid #9e9679;
margin-bottom: 10px;
}
.title{
font-weight: bold;
}
.desc{
margin-top: 5px;
line-height: 1.5em;
}
#page-loading{
display: none;
padding: 10px;
background: #ffcece;
}
#page-footer{
padding: 10px;
background: #d1daff;
}
This is very straightforward as well, with just some cosmetics – Feel free to make your own changes, or totally discard it if you already have your own project.
STEP 2
SERVER-SIDE SCRIPTS
Next, we shall dive into the server-side scripts, on how to extract content from the MYSQL database to form proper HTML.
CONFIG FILE
This config file contains all the settings and stuff.
- I have muted the notice “error” messages. For those who do not know, PHP has several levels of error reporting. Notices are non-critical “mistakes” that will not break the system… They are just kind of naggy for all kinds of small mistakes.
- The database settings should be self-explanatory, just remember to change these to your own.
- The per page setting is used to restrict the number of content entries to pull out every AJAX call… So that you don’t kill the server trying to extract a content tsunami.
CONTENT LIBRARY
pdo = new PDO(
"mysql:host=".DB_HOST.";dbname=".DB_NAME.";charset=".DB_CHARSET, DB_USER, DB_PASSWORD, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
PDO::ATTR_EMULATE_PREPARES => false]
);
return true;
} catch (Exception $ex) {
die($ex->getMessage());
}
}
function __destruct() {
if ($this->stmt !== null) { $this->stmt = null; }
if ($this->pdo !== null) { $this->pdo = null; }
}
function get ($start=0, $end=10) {
$q = "SELECT * FROM `contents` ORDER BY `id` LIMIT $start, $end";
$this->stmt = $this->pdo->prepare($q);
$this->stmt->execute();
$results = $this->stmt->fetchAll();
return count($results)==0 ? false : $results ;
}
}
?>
This library file works with the MYSQL database to extract the content entries.
- The constructor will automatically connect to the database when the content object is being created.
- The destructor will automatically close the database connection when the object is being destroyed.
- Finally, it has a get function to fetch the content entries – It takes 2 parameters, the starting and ending entry number, which is used for “pagination”.
AJAX HANDLER
get($start, $end);
// SPIT HTML
if (is_array($contents)) { foreach ($contents as $c) { ?>
=$c['id']?>) =$c['title']?>
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Aliquam et nisi condimentum lectus sagittis facilisis vel eu nisi.
Integer sit amet leo vitae urna posuere facilisis.
Of course, the library will not do anything by itself, so we will need a script that uses the library to pull out the contents. This one is very straightforward –
- It simply pulls the content entries from the database and outputs them in HTML.
- This script takes a
$_POST['page']
to calculate the number of entries to extract. - The
PER_PAGE
setting in the config file will determine the number of entries to extract in this script. - For example, if we post
$_POST['page'] = 1
andPER_PAGE = 10
, the script will draw entries 0 to 10. - If we post
$_POST['page'] = 2
, the script will draw entries 10 to 20, and so on… - When no more entries can be drawn from the database, this script simply outputs an “END” to indicate that there are no more contents to be loaded.
STEP 3
THE JAVASCRIPT
We now have the base page HTML and the server-side scripts ready. All that is left is to “bridge” them by loading contents via AJAX… Which is also the most complicated part of this tutorial.
THE SCRIPT
var endless = {
page: 0, // "current page",
hasMore: true, // not at the end, has more contents
proceed: true, // load the next page?
load: function () {
if (endless.proceed && endless.hasMore) {
// Prvent user from loading too much contents suddenly
// Block the loading until this one is done
endless.proceed = false;
// Load the next page
var data = new FormData(),
nextPg = endless.page + 1,
loading = document.getElementById("page-loading");
data.append('page', nextPg);
// Show loading message or spinner
loading.style.display = "block";
// AJAX request
var xhr = new XMLHttpRequest();
xhr.open('POST', "ajax-contents.php", true);
xhr.onload = function () {
// No more contents to load
if (this.response == "END") {
loading.innerHTML = "END";
endless.hasMore = false;
}
// Contents loaded
else {
// Append into container + hide loading message
var el = document.createElement('div');
el.innerHTML = this.response;
document.getElementById("page-content").appendChild(el);
loading.style.display = "none";
// Set the current page, unblock loading
endless.page = nextPg;
endless.proceed = true;
}
};
xhr.send(data);
}
},
listen: function(){
// Get the height of the entire document
var height = document.documentElement.offsetHeight,
// Get the current offset - how far "scrolled down"
offset = document.documentElement.scrollTop + window.innerHeight;
// Check if user has hit the end of page
// console.log('Height: ' + height);
// console.log('Offset: ' + offset);
if (offset === height) {
endless.load();
}
}
};
window.onload = function () {
// Attach scroll listener
window.addEventListener("scroll", endless.listen);
// Initial load contents
endless.load();
};
This script looks like a handful to digest at first, but all it does is actually just 2 main things:
- Detects if the user has scrolled down to the bottom of the page.
- Loads more contents via AJAX as it hits the bottom of the page.
HOW IT WORKS, STEP-BY-STEP
The endless
object will do most of the heavy lifting.
page | Keeps track of the current page. |
hasMore | A flag used to track if the server has more contents – True by default. |
proceed | A flag used to track if an AJAX method is already running in the background. |
load | Loads more content from the server via AJAX. |
listen | Listens to the page scroll. Calls load when the user hits the bottom of the page. |
- When the window is fully loaded, the page scroll
listen
method will be attached. - The
load
method is then called to populate the initial contents. - Every time the
load
method is being called, it will only run if the server has more contents to offer and when there are no other AJAX requests in the background –hasMore==true && proceed==true
- The
proceed
flag will be set tofalse
, to prevent too much contents to be loaded at once; Stop the script from firing too many times when it is still loading. - An AJAX request will be made to the server side, attempting to fetch the next page –
nextPg = endless.page + 1
- Upon successful loading, the contents will be populated into the
#page-content
container, and the current page plus proceed flags updated –endless.page = nextPg; endless.proceed = true;
. This will “unblock” the script and allow loading when the user hits the end of the page again. - If the server returns an “end”, it indicates that there are no more contents to be served. The
hasMore
flag will be set tofalse
, preventing any further AJAX loads.
EXTRA
DOWNLOAD & MORE
That’s the end of the scripts, and here is the download link plus a little bit of an extra that you may find useful.
EXTRA) INFINITE SCROLLING – REALLY?
Technically, we can load and serve an infinite amount of contents this way. But you have to consider that computers still have finite memory and system resources… Plus, do you really have that much contents to serve? So even though this is called “infinite scroll”, there still has to be a limit in order to prevent browser crashes.
Also, one bad news for you SEO lovers – Even though some search engines are smart enough to understand AJAX calls, they may not “scroll down” to load more contents; Infinite scrolling is only good for certain types of contents, and please do not use it to “hide” your useful contents… For example, “scroll down to read more” for an article. You will end up on the bad side of SEO practice instead.
DOWNLOAD
Click here to download the source code, I have released it under the MIT license, so feel free to build on top of it or use it in your own project.
CLOSING
WHAT’S NEXT?
We have come to the end of this guide, and I hope that it has helped you to build a better project. If you have some stuff to add to this guide, please feel free to comment below. Good luck and happy coding!
The post 3 Steps Infinite Scroll with Vanilla Javascript appeared first on Code Boxx.