I have "translated" this example built with jQuery in vanilla JavaScript, but I'd like to know if there are better ways to do it.
The jQuery version uses offset()
function and on()
for every events, while I've used this function for offset:
function offset(elt) {
var rect = elt.getBoundingClientRect(), bodyElt = document.body;
return {
top: rect.top + bodyElt .scrollTop,
left: rect.left + bodyElt .scrollLeft
}
}
and this one to prefix AnimationEnd
event :
var pfx = ["webkit", "moz", "MS", "o", ""];
function prefixedEvent(element, type, callback) {
for (var p = 0; p < pfx.length; p++) {
if (!pfx[p]) type = type.toLowerCase();
element.addEventListener(pfx[p]+type, callback, false);
}
}
From this sitepoint article
My entire code is visible here at Codepen.
Otherwise, here is my example code:
HTML
<button>
<span class="ripples">
<span class="ripples-circle"></span>
</span>Test
</button>
<button>
<span class="ripples">
<span class="ripples-circle"></span>
</span>Test
</button>
<button>
<span class="ripples">
<span class="ripples-circle"></span>
</span>Test
</button>
SCSS (without prefixes):
button {
height: 100px;
width: 100px;
background-color: gray;
border-style:solid;
color: #fff;
position: relative;
display: inline-block;
padding: 12px 24px;
margin-top: 0;
margin-bottom: 0;
vertical-align: middle;
transition: all .25s ease;
&:focus {
outline: 0;
}
&:hover {
background-color: darken(gray, 5%);
}
}
.ripples {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
overflow: hidden;
background-color: transparent;
&.is-active {
.ripples-circle {
animation: ripples .4s ease-in;
}
}
.ripples-circle {
background-color: rgba(255,255,255,.5);
position: absolute;
top: 50%;
left: 50%;
opacity: 0;
width: 0;
height: 0;
border-radius: 50%;
transform: translate(-50%, -50%);
}
}
@keyframes ripples {
0% {
opacity: 0;
}
25% {
opacity: 1;
}
100% {
width: 200%;
padding-bottom: 200%;
opacity: 0;
}
}
JavaScript:
(function(window, document, undefined){
'use strict';
//http://www.debray-jerome.fr/js-performance-la-fonction-offset-de-jquery-vs-vanilla-javascript-23.html
function offset(elt) {
var rect = elt.getBoundingClientRect(), bodyElt = document.body;
return {
top: rect.top + bodyElt .scrollTop,
left: rect.left + bodyElt .scrollLeft
}
}
//http://www.sitepoint.com/css3-animation-javascript-event-handlers/
var pfx = ["webkit", "moz", "MS", "o", ""];
function prefixedEvent(element, type, callback) {
for (var p = 0; p < pfx.length; p++) {
if (!pfx[p]) type = type.toLowerCase();
element.addEventListener(pfx[p]+type, callback, false);
}
}
var ripples = document.querySelectorAll('.ripples');
for(var i=0; i < ripples.length;i++ ){
ripples[i].addEventListener('click', function(e){
var rippleThis = this;
var parentOffset = offset(rippleThis.parentNode);
var x = e.pageX - parentOffset.left;
var y = e.pageY + parentOffset.top;
var j;
var childrenLength = rippleThis.childNodes.length;
var targetChild;
for(j = 0; j < childrenLength; j++){
if(rippleThis.childNodes[j].className == 'ripples-circle') targetChild = rippleThis.childNodes[j];
}
targetChild.style.top = y + 'px';
targetChild.style.left = x + 'px';
rippleThis.className = 'ripples is-active';
}, false);
prefixedEvent(ripples[i], "AnimationEnd", function(e){
e.currentTarget.className = 'ripples';
});
}
})(window, document);