参考http://www.materializecss.cn/waves.html
<html lang="en"> <head>
<meta charset="UTF-8">
<title>Document</title>
<style>
p {
height: 100px;
line-height: 100px;
text-align: center;
width: 100px;
background-color: #ccc;
}
/* Firefox Bug: link not triggered */ .waves-effect .waves-ripple {
z-index: -1;
} .waves-effect {
position: relative;
cursor: pointer;
display: inline-block;
overflow: hidden;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
-webkit-tap-highlight-color: transparent;
vertical-align: middle;
z-index: 1;
-webkit-transition: .3s ease-out;
transition: .3s ease-out;
} .waves-effect .waves-ripple {
position: absolute;
border-radius: 50%;
width: 20px;
height: 20px;
margin-top: -10px;
margin-left: -10px;
opacity: 0;
background: rgba(0, 0, 0, 0.2);
-webkit-transition: all 0.7s ease-out;
transition: all 0.7s ease-out;
-webkit-transition-property: opacity, -webkit-transform;
transition-property: opacity, -webkit-transform;
transition-property: transform, opacity;
transition-property: transform, opacity, -webkit-transform;
-webkit-transform: scale(0);
transform: scale(0);
pointer-events: none;
}
/*.waves-light此类class是wave颜色*/ .waves-effect.waves-light .waves-ripple {
background-color: rgba(255, 255, 255, 0.45);
} .waves-effect.waves-red .waves-ripple {
background-color: rgba(244, 67, 54, 0.7);
} .waves-effect.waves-yellow .waves-ripple {
background-color: rgba(255, 235, 59, 0.7);
} .waves-effect.waves-orange .waves-ripple {
background-color: rgba(255, 152, 0, 0.7);
} .waves-effect.waves-purple .waves-ripple {
background-color: rgba(156, 39, 176, 0.7);
} .waves-effect.waves-green .waves-ripple {
background-color: rgba(76, 175, 80, 0.7);
} .waves-effect.waves-teal .waves-ripple {
background-color: rgba(0, 150, 136, 0.7);
} .waves-effect img {
position: relative;
z-index: -1;
}
</style>
</head> <body> <p class="waves-effect waves-orange">ppppp</p> <script>
if ('ontouchstart' in window) {
document.body.addEventListener('touchstart', showEffect, false);
}
document.body.addEventListener('mousedown', showEffect, false);
var TouchHandler = {
/* uses an integer rather than bool so there's no issues with
* needing to clear timeouts if another touch event occurred
* within the 500ms. Cannot mouseup between touchstart and
* touchend, nor in the 500ms after touchend. */
touches: 0,
allowEvent: function(e) {
var allow = true; if (e.type === 'touchstart') {
TouchHandler.touches += 1; //push
} else if (e.type === 'touchend' || e.type === 'touchcancel') {
setTimeout(function() {
if (TouchHandler.touches > 0) {
TouchHandler.touches -= 1; //pop after 500ms
}
}, 500);
} else if (e.type === 'mousedown' && TouchHandler.touches > 0) {
allow = false;
} return allow;
},
touchup: function(e) {
TouchHandler.allowEvent(e);
}
};
var Effect = {
// Effect delay
duration: 750, show: function(e, element) { // Disable right click
if (e.button === 2) {
return false;
} var el = element || this; // Create ripple
var ripple = document.createElement('div');
ripple.className = 'waves-ripple';
el.appendChild(ripple); // Get click coordinate and element witdh
var pos = offset(el);
var relativeY = e.pageY - pos.top;
var relativeX = e.pageX - pos.left;
var scale = 'scale(' + el.clientWidth / 100 * 10 + ')'; // Support for touch devices
if ('touches' in e) {
relativeY = e.touches[0].pageY - pos.top;
relativeX = e.touches[0].pageX - pos.left;
} // Attach data to element
ripple.setAttribute('data-hold', Date.now());
ripple.setAttribute('data-scale', scale);
ripple.setAttribute('data-x', relativeX);
ripple.setAttribute('data-y', relativeY); // Set ripple position
var rippleStyle = {
'top': relativeY + 'px',
'left': relativeX + 'px'
}; ripple.className = ripple.className + ' waves-notransition';
ripple.setAttribute('style', convertStyle(rippleStyle));
ripple.className = ripple.className.replace('waves-notransition', ''); // Scale the ripple
rippleStyle['-webkit-transform'] = scale;
rippleStyle['-moz-transform'] = scale;
rippleStyle['-ms-transform'] = scale;
rippleStyle['-o-transform'] = scale;
rippleStyle.transform = scale;
rippleStyle.opacity = '1'; rippleStyle['-webkit-transition-duration'] = Effect.duration + 'ms';
rippleStyle['-moz-transition-duration'] = Effect.duration + 'ms';
rippleStyle['-o-transition-duration'] = Effect.duration + 'ms';
rippleStyle['transition-duration'] = Effect.duration + 'ms'; rippleStyle['-webkit-transition-timing-function'] = 'cubic-bezier(0.250, 0.460, 0.450, 0.940)';
rippleStyle['-moz-transition-timing-function'] = 'cubic-bezier(0.250, 0.460, 0.450, 0.940)';
rippleStyle['-o-transition-timing-function'] = 'cubic-bezier(0.250, 0.460, 0.450, 0.940)';
rippleStyle['transition-timing-function'] = 'cubic-bezier(0.250, 0.460, 0.450, 0.940)'; ripple.setAttribute('style', convertStyle(rippleStyle));
}, hide: function(e) {
TouchHandler.touchup(e); var el = this;
var width = el.clientWidth * 1.4; // Get first ripple
var ripple = null;
var ripples = el.getElementsByClassName('waves-ripple');
if (ripples.length > 0) {
ripple = ripples[ripples.length - 1];
} else {
return false;
} var relativeX = ripple.getAttribute('data-x');
var relativeY = ripple.getAttribute('data-y');
var scale = ripple.getAttribute('data-scale'); // Get delay beetween mousedown and mouse leave
var diff = Date.now() - Number(ripple.getAttribute('data-hold'));
var delay = 350 - diff; if (delay < 0) {
delay = 0;
} // Fade out ripple after delay
setTimeout(function() {
var style = {
'top': relativeY + 'px',
'left': relativeX + 'px',
'opacity': '0', // Duration
'-webkit-transition-duration': Effect.duration + 'ms',
'-moz-transition-duration': Effect.duration + 'ms',
'-o-transition-duration': Effect.duration + 'ms',
'transition-duration': Effect.duration + 'ms',
'-webkit-transform': scale,
'-moz-transform': scale,
'-ms-transform': scale,
'-o-transform': scale,
'transform': scale
}; ripple.setAttribute('style', convertStyle(style)); setTimeout(function() {
try {
el.removeChild(ripple);
} catch (e) {
return false;
}
}, Effect.duration);
}, delay);
}
} function showEffect(e) {
var element = getWavesEffectElement(e);
if (element !== null) {
Effect.show(e, element); if ('ontouchstart' in window) {
element.addEventListener('touchend', Effect.hide, false);
element.addEventListener('touchcancel', Effect.hide, false);
} element.addEventListener('mouseup', Effect.hide, false);
element.addEventListener('mouseleave', Effect.hide, false);
element.addEventListener('dragend', Effect.hide, false);
}
}; function getWavesEffectElement(e) { if (TouchHandler.allowEvent(e) === false) {
return null;
} var element = null;
var target = e.target || e.srcElement; while (target.parentNode !== null) {
if (!(target instanceof SVGElement) && target.className.indexOf('waves-effect') !== -1) {
element = target;
break;
}
target = target.parentNode;
}
return element;
} function offset(elem) {
var docElem,
win,
box = { top: 0, left: 0 },
doc = elem && elem.ownerDocument; docElem = doc.documentElement; if (typeof elem.getBoundingClientRect !== typeof undefined) {
box = elem.getBoundingClientRect();
}
win = getWindow(doc);
return {
top: box.top + win.pageYOffset - docElem.clientTop,
left: box.left + win.pageXOffset - docElem.clientLeft
};
} function isWindow(obj) {
return obj !== null && obj === obj.window;
} function getWindow(elem) {
return isWindow(elem) ? elem : elem.nodeType === 9 && elem.defaultView;
} function convertStyle(obj) {
var style = ''; for (var a in obj) {
if (obj.hasOwnProperty(a)) {
style += a + ':' + obj[a] + ';';
}
} return style;
}
</script> </body> </html>