自建的自定义指令文件中
import Vue from "vue";
Vue.directive('ripple',{
inserted(el,binding){
el.addEventListener('mouseup',(e)=>{
// -------------------------------负责给按钮所在的样式表添加@keyframes动画-------------------------------
const sheet = document.styleSheets[0]//获取本页的样式表。[0]表示本页所有样式表中的第一个表
// 样式表中的rules(是一个对象,有length:xx和0:xxx,1:xxx这些属性。不是数组,不能通过rules[0]等方法拿到)
const keyframesIndex = sheet.rules.length-1
const keyframes = sheet.rules[keyframesIndex]
// 样式表中的最后一项是不是波纹动画?是就不在添加,不是就向样式表的最后添加波纹动画
if(keyframes.name !== 'ripple'){
let keyframesRipple = `@keyframes ripple {
0% {
transform: scale(0);
opacity: 1;
}
100% {
transform: scale(2);
opacity: 0;
}
}`
sheet.insertRule(keyframesRipple,keyframesIndex + 1)
}
// -------------------------------------------------------------------------------------------------------
let rippleTime = (binding.value && binding.value.time) || 700 //有传入时间就用传入的
let rippleColor = (binding.value && binding.value.color) || 'rgba(255,255,255,0.5)' //有传入的颜色就用传入的
// 拿到需要波纹效果的按钮
const target = e.currentTarget
// 创建波纹元素
const ripple = document.createElement('span')
// 给按钮元素添加波纹相关样式
target.style['-webkit-tap-highlight-color'] = 'transparent'//去除点击时出现的默认淡蓝色背景
target.style.position = 'relative'
target.style.overflow = 'hidden'
// 给波纹元素添加波纹相关样式
ripple.style.position = 'absolute'
ripple.style.borderRadius = '50%'
ripple.style.transform = 'scale(0)'
ripple.style.cursor = 'pointer'
// 设置波纹元素的大小
const rippleHeightAndWidth = Math.max(target.clientHeight,target.clientWidth)//波纹元素的大小需要根据目标按钮的长宽的最大值来定
const radius = rippleHeightAndWidth / 2 //波纹元素的半径
ripple.style.height = rippleHeightAndWidth + 'px' //设置波纹元素的高度
ripple.style.width = rippleHeightAndWidth + 'px' //设置波纹元素的宽度
//根据参数设置波纹元素的动画时间
ripple.style.animation = `ripple ${rippleTime}ms linear`//ripple动画方法的开头已添加
//根据参数设置波纹元素的颜色
ripple.style.backgroundColor = rippleColor
// 设置波纹起始点(中心点)的位置
let left = e.clientX - target.offsetLeft - radius//波纹元素相对于按钮的的left = 鼠标的X坐标 - 按钮左侧距离视口的距离,再减去半径才是中心点的位置
let top = e.clientY - target.offsetTop - radius//波纹元素相对于按钮的的top = 鼠标的Y坐标 - 按钮上侧侧距离视口的距离,再减去半径才是中心点的位置
ripple.style.left = left + 'px' //设置波纹元素的定位的left
ripple.style.top = top + 'px' //设置波纹元素的定位的top
// 将波纹元素插入按钮的子元素中
target.appendChild(ripple)//插入
// 延迟(动画时间的长度)后删除该波纹元素
setTimeout(()=>{
target.removeChild(ripple)
},rippleTime)
})
}
})
main.js中引入
import '@/assets/js/ripple.js'
需要的地方使用
<div class="button" v-ripple>搜索</div>
或者传入参数
<div class="button" v-ripple="{time:200,color:'red'}">搜索</div>