效果如下:
思路:
按钮及按钮的父标签定位需为绝对定位或相对定位
绑定按钮的click事件,把其样式设置为overflow:hidden,并添加下标线标签并设置其样式
当鼠标点击按钮时,如果按钮内有标签(波兰纹)即把该标签删掉,
注:必须先添加标签然后计算标签样式再更改其相应样式,如果先计算样式然后添加标签后立即接修改其样式,有可能出现修改样式时获取不到标签的问题;
获取目标事件的位置pageX和pageY,及按钮距离页面的左边和顶部的距离,通过计算获取标签(波浪纹)的top,left,width,height值(宽高为按钮的两倍),
先把标签(波浪纹)缩放值设为0,transition为.4s,然后再修改其缩放值为1.5,透明度为0,并通过调用animate方法在实现动画效果后删除该标签
按钮的active类名作用: 用来判断是否需要修改下标线的位置及宽度
使用时调用按钮父标签的wave方法(按钮类名是必传的)
示例代码:
CSS:
.ul{display:flex; display:-webkit-flex; position:relative; width:600px; margin:auto; text-align:center; color:white;cursor: pointer;}
.ul .li{position:relative; width:200px; height:60px; line-height:60px; background: orange;}
HTML:
<div class="ul">
<div class="li">TAG FIRST</div>
<div class="li">TAG SECOND</div>
<div class="li">TAG THIRD</div>
</div>
<script id="jquery_183" type="text/javascript" class="library" src="http://code.jquery.com/jquery-latest.js"></script>
JS:
;(function($){
$.fn.wave=function(options){
var defaults={
lineColor: 'white',//默认下标线颜色
lineHeight: 4,//默认下标线高度
waveColor: 'lightblue',//默认波浪颜色
index: 0//默认选中标签下标
}
var options= $.extend({}, defaults, options);
this.each(function(){
var $this = $(this);
var $buttons = $('.'+options.btnClass, $this);
$this.append(`<div class="line" style="position:absolute;transition:.5s;-webkit-transition:.5s;-moz-transition:.5s;-o-transition:.5s;bottom:0;left:${$buttons[options.index].offsetLeft}px;width:${$buttons[options.index].clientWidth}px;height:${options.lineHeight}px;background:${options.lineColor};"><div>`);
var $line = $('.line', $this),//下标线
leftDistance = getLeftDistance(this),//按钮父元素到页面左边的距离
topDistance = getTopDistance(this);//按钮父元素到页面顶端的距离
$buttons.each(function(){
$(this).css("overflow","hidden").click(function(e){
var event = e || event;
var $this = $(this);
$(".wave",$this).remove();
$this.append(`<div class="wave" style="position:absolute;transform:scale(0);-webkit-transform:scale(0);border-radius:50%;background:${options.waveColor};opacity:0.4;"></div>`);
var x = event.pageX,//鼠标位置到页面左边的距离(包括滚动距离)
y = event.pageY,//鼠标位置到页面顶端的距离(包括滚动距离)
w = this.clientWidth,//按钮的宽
h = this.clientHeight,//按钮的高
offsetLeft = this.offsetLeft,//按钮到其父元素左边的距离
offsetTop = this.offsetTop,//按钮到其父元素顶端的距离
left = leftDistance + offsetLeft,
top = topDistance + offsetTop;
if(w > h){
h = w;
}else{
w = h;
}
var left = x - w - left,
top = y - h - top;
var $wave = $('.wave', $this);
if(!$this.hasClass('active')){
$this.addClass('active').siblings().removeClass('active');
$line.css({left: offsetLeft, width: w});
}
var transition = prefixStyle('transition');
var transform = prefixStyle('transform');
var css_first = {
width: w * 2+'px',
height: h * 2 + 'px',
left: left + 'px',
top: top + 'px'
}
var css_second = {
opacity: 0
}
css_first[transition] = '.4s linear';
css_second[transform] = 'scale(1.5)';
$wave.css(css_first).css(css_second).animate({opacity: 0},400,function(){
$(this).remove()
});
})
})
});
return this;
}
})(jQuery)
//调用方式:
window.onload = function(){
$('.ul').wave({
lineColor:'red', //下标线颜色
lineHeight: 4, //下标线高度
waveColor: 'lightgray', //波浪颜色
index: 0, //选中标签下标
btnClass: 'li' //按钮类名(必须传)
});
}
/**** 公用方法 ****/
//获取标签距离文档左边的距离:
var elementStyle = document.createElement('div').style;
function getLeftDistance (element){
var actualLeft = element.offsetLeft,
current = element.offsetParent;
while (current !== null){
actualLeft += current.offsetLeft;
current = current.offsetParent;
}
return actualLeft;
}
//获取标签距离文档上边的距离:
function getTopDistance (element){
var actualTop = element.offsetTop,
current = element.offsetParent;
while (current !== null){
actualTop += current. offsetTop;
current = current.offsetParent;
}
return actualTop;
}
//获取样式前缀
var vendor = (() => {
var transformNames = {
webkit: 'webkitTransform',
Moz: 'MozTransform',
O: 'OTransform',
ms: 'msTransform',
standard: 'transform'
}
for (var key in transformNames) {
if (elementStyle[transformNames[key]] !== undefined) {
return key
}
}
return false
})()
//获取样式属性(带前缀)
function prefixStyle (style) {
if (vendor === false) {
return false
}
if (vendor === 'standard') {
return style
}
return vendor + style.charAt(0).toUpperCase() + style.substr(1)
}
/**** 公用方法 ****/
在线演示:http://sandbox.runjs.cn/show/tt9xdkvx