EN
JavaScript - how to create custom animated loader?
11
points
In JavaScript it is possible to create simple animated loader in following way.
1. JavaScriopt loader in single file example
Note: this source code has been splitted in to separated files in second example to make it easier to read.
// ONLINE-RUNNER:browser;
<!doctype html>
<html>
<head>
<style>
.loadable-content {
position: relative;
}
.content-cover {
position: absolute;
left: 0; top: 0; right: 0; bottom: 0;
background: rgba(0, 0, 0, 0.2);
z-index: 1000000;
}
.content-loader {
margin: -55px 0 0 -55px;
position: absolute;
left: 50%; top: 50%;
border-radius: 50%;
background: rgba(255, 255, 255, 0.1);
width: 110px; height: 110px;
}
.content-loader-item {
position: absolute;
left: 45px; top: 45px;
border-radius: 50%;
background: silver;
width: 20px; height: 20px;
color: red;
}
.content-loader-item:nth-child(1) {
transform: rotate(0deg) translate(0, 40px);
animation: content-loader-item-animation infinite 2s 0.125s linear;
}
.content-loader-item:nth-child(2) {
transform: rotate(45deg) translate(0, 40px);
animation: content-loader-item-animation infinite 2s 0.250s linear;
}
.content-loader-item:nth-child(3) {
transform: rotate(90deg) translate(0, 40px);
animation: content-loader-item-animation infinite 2s 0.375s linear;
}
.content-loader-item:nth-child(4) {
transform: rotate(135deg) translate(0, 40px);
animation: content-loader-item-animation infinite 2s 0.500s linear;
}
.content-loader-item:nth-child(5) {
transform: rotate(180deg) translate(0, 40px);
animation: content-loader-item-animation infinite 2s 0.625s linear;
}
.content-loader-item:nth-child(6) {
transform: rotate(225deg) translate(0, 40px);
animation: content-loader-item-animation infinite 2s 0.750s linear;
}
.content-loader-item:nth-child(7) {
transform: rotate(270deg) translate(0, 40px);
animation: content-loader-item-animation infinite 2s 0.875s linear;
}
.content-loader-item:nth-child(8) {
transform: rotate(315deg) translate(0, 40px);
animation: content-loader-item-animation infinite 2s 1.000s linear;
}
@keyframes content-loader-item-animation {
0.0% {
background: #b5b5b5;
}
20.0% {
background: #808080;
}
25.0% {
background: #c0c0c0;
}
100.0% {
background: #c0c0c0;
}
}
</style>
<script>
'use strict';
(function(window) {
window.Loader = function() {
var container = document.createElement('div');
container.innerHTML = '' +
'<div class="content-cover">\n' +
' <div class="content-loader">\n' +
' <div class="content-loader-item"></div>\n' +
' <div class="content-loader-item"></div>\n' +
' <div class="content-loader-item"></div>\n' +
' <div class="content-loader-item"></div>\n' +
' <div class="content-loader-item"></div>\n' +
' <div class="content-loader-item"></div>\n' +
' <div class="content-loader-item"></div>\n' +
' <div class="content-loader-item"></div>\n' +
' </div>\n' +
'</div>';
var element = container.firstChild;
this.show = function(parent, placeholder) {
parent.insertBefore(element, placeholder);
};
this.hide = function() {
var parent = element.parentNode;
if(parent) {
parent.removeChild(element);
}
};
};
})(window);
</script>
</head>
<body>
<style>
#container {
border: 1px solid red;
height: 150px;
}
</style>
<div id="container" class="loadable-content">
This is some text...<br />
This is some text...<br />
This is some text...<br />
This is some text...<br />
This is some text...<br />
This is some text...
</div>
<br />
<div>
<button onclick="turnOnLoader()">Turn ON loader</button>
<button onclick="turnOffLoader()">Turn OFF loader</button>
</div>
<script>
var container = document.querySelector('#container');
var loader = new Loader();
function turnOnLoader() {
loader.show(container);
}
function turnOffLoader() {
loader.hide();
}
</script>
</body>
</html>
2. JavaScriopt loader in separated files example
index.htm
file:
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" href="loader.css" />
<script src="loader.js"></script>
</head>
<body>
<style>
#container {
border: 1px solid red;
height: 150px;
}
</style>
<div id="container" class="loadable-content">
This is some text...<br />
This is some text...<br />
This is some text...<br />
This is some text...<br />
This is some text...<br />
This is some text...
</div>
<br />
<div>
<button onclick="turnOnLoader()">Turn ON loader</button>
<button onclick="turnOffLoader()">Turn OFF loader</button>
</div>
<script>
var container = document.querySelector('#container');
var loader = new Loader();
function turnOnLoader() {
loader.show(container);
}
function turnOffLoader() {
loader.hide();
}
</script>
</body>
</html>
Result:

loader.js
file:
'use strict';
(function(window) {
window.Loader = function() {
var container = document.createElement('div');
container.innerHTML = '' +
'<div class="content-cover">\n' +
' <div class="content-loader">\n' +
' <div class="content-loader-item"></div>\n' +
' <div class="content-loader-item"></div>\n' +
' <div class="content-loader-item"></div>\n' +
' <div class="content-loader-item"></div>\n' +
' <div class="content-loader-item"></div>\n' +
' <div class="content-loader-item"></div>\n' +
' <div class="content-loader-item"></div>\n' +
' <div class="content-loader-item"></div>\n' +
' </div>\n' +
'</div>';
var element = container.firstChild;
this.show = function(parent, placeholder) {
parent.insertBefore(element, placeholder);
};
this.hide = function() {
var parent = element.parentNode;
if(parent) {
parent.removeChild(element);
}
};
};
})(window);
loader.css
file:
.loadable-content {
position: relative;
}
.content-cover {
position: absolute;
left: 0; top: 0; right: 0; bottom: 0;
background: rgba(0, 0, 0, 0.2);
z-index: 1000000;
}
.content-loader {
margin: -55px 0 0 -55px;
position: absolute;
left: 50%; top: 50%;
border-radius: 50%;
background: rgba(255, 255, 255, 0.1);
width: 110px; height: 110px;
}
.content-loader-item {
position: absolute;
left: 45px; top: 45px;
border-radius: 50%;
background: silver;
width: 20px; height: 20px;
color: red;
}
.content-loader-item:nth-child(1) {
transform: rotate(0deg) translate(0, 40px);
animation: content-loader-item-animation infinite 2s 0.125s linear;
}
.content-loader-item:nth-child(2) {
transform: rotate(45deg) translate(0, 40px);
animation: content-loader-item-animation infinite 2s 0.250s linear;
}
.content-loader-item:nth-child(3) {
transform: rotate(90deg) translate(0, 40px);
animation: content-loader-item-animation infinite 2s 0.375s linear;
}
.content-loader-item:nth-child(4) {
transform: rotate(135deg) translate(0, 40px);
animation: content-loader-item-animation infinite 2s 0.500s linear;
}
.content-loader-item:nth-child(5) {
transform: rotate(180deg) translate(0, 40px);
animation: content-loader-item-animation infinite 2s 0.625s linear;
}
.content-loader-item:nth-child(6) {
transform: rotate(225deg) translate(0, 40px);
animation: content-loader-item-animation infinite 2s 0.750s linear;
}
.content-loader-item:nth-child(7) {
transform: rotate(270deg) translate(0, 40px);
animation: content-loader-item-animation infinite 2s 0.875s linear;
}
.content-loader-item:nth-child(8) {
transform: rotate(315deg) translate(0, 40px);
animation: content-loader-item-animation infinite 2s 1.000s linear;
}
@keyframes content-loader-item-animation {
0.0% {
background: #b5b5b5;
}
20.0% {
background: #808080;
}
25.0% {
background: #c0c0c0;
}
100.0% {
background: #c0c0c0;
}
}