patternjavascriptMinor
Google material ripple button effect
Viewed 0 times
rippleeffectgooglematerialbutton
Problem
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
and this one to prefix
From this sitepoint article
My entire code is visible here at Codepen.
Otherwise, here is my example code:
HTML
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% {
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
Test
Test
Test
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% {
Solution
Some things that I would do differently in this for loop
First thing I saw was that you created an increment variable outside of the for loop declaration, that just makes things a little messy, there isn't any reason for
You should also give your code some breathing room, like in the for loop declaration
After all these changes it would look like this
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';
});
}First thing I saw was that you created an increment variable outside of the for loop declaration, that just makes things a little messy, there isn't any reason for
var j; outside of the for loop.rippleThis isn't a good variable name, I would name this variable thisRipple because it is literally this ripple object.You should also give your code some breathing room, like in the for loop declaration
var i = 0; i < ripples.length; i++ looks better than var i=0; i < ripples.length;i++After all these changes it would look like this
for(var i = 0; i < ripples.length; i++ ){
ripples[i].addEventListener('click', function(e){
var thisRipple = this;
var parentOffset = offset(thisRipple.parentNode);
var x = e.pageX - parentOffset.left;
var y = e.pageY + parentOffset.top;
var childrenLength = thisRipple.childNodes.length;
var targetChild;
for(var j = 0; j < childrenLength; j++){
if(thisRipple.childNodes[j].className == 'ripples-circle') targetChild = thisRipple.childNodes[j];
}
targetChild.style.top = y + 'px';
targetChild.style.left = x + 'px';
thisRipple.className = 'ripples is-active';
}, false);
prefixedEvent(ripples[i], "AnimationEnd", function(e){
e.currentTarget.className = 'ripples';
});
}Code Snippets
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';
});
}for(var i = 0; i < ripples.length; i++ ){
ripples[i].addEventListener('click', function(e){
var thisRipple = this;
var parentOffset = offset(thisRipple.parentNode);
var x = e.pageX - parentOffset.left;
var y = e.pageY + parentOffset.top;
var childrenLength = thisRipple.childNodes.length;
var targetChild;
for(var j = 0; j < childrenLength; j++){
if(thisRipple.childNodes[j].className == 'ripples-circle') targetChild = thisRipple.childNodes[j];
}
targetChild.style.top = y + 'px';
targetChild.style.left = x + 'px';
thisRipple.className = 'ripples is-active';
}, false);
prefixedEvent(ripples[i], "AnimationEnd", function(e){
e.currentTarget.className = 'ripples';
});
}Context
StackExchange Code Review Q#82060, answer score: 3
Revisions (0)
No revisions yet.