先上代码
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><style>div {width: 100px;height: 100px;background-color: red;margin-bottom: 50px;opacity: 0.2;}</style>
</head>
<body><header><div></div><div></div><div></div><div></div></header><script>// 获取header元素header = document.querySelector('header')// 设置鼠标移入时的事件header.onmouseover = function (e) {if (e.target.tagName == 'DIV'){startMove(e.target,{height: 500,width: 500,// 这里要注意将透明度乘以100opacity: 100})}}// 设置鼠标移出时的事件header.onmouseout = function (e) {if (e.target.tagName == 'DIV'){startMove(e.target,{height: 100,width: 100,opacity: 20})}}function startMove(dom, attrObj){// 将速度设置在定时器外部,因为达到缓冲效果,需要速度不停变化var speed = null// 为了不同dom之间的定时器互不干扰,给dom添加定时器属性// 某个定时器只属于某个domclearInterval(dom.timer)dom.timer = setInterval(function(){// 设置定时器的锁,用于判断是否清除定时器var bStop = true// 遍历attrObj 将对象中的每一个属性进行运动for (var attr in attrObj) {//判断属性是否是透明度 分开获取样式属性if (attr == 'opacity'){// 使透明度变化更明显,不然下面取整时一下就到1,没有缓冲的效果var iCur = parseFloat(window.getComputedStyle(dom).opacity) * 100}else{// 获取当前最终样式的属性var iCur = parseFloat(window.getComputedStyle(dom)[attr])}// 求出速度 变化步长// 此速度随着目标属性值与当前属性值的接近速度会越来越小,// 达到缓冲的效果,不是7也可以,随便除以一个数字即可speed = (attrObj[attr] - iCur) / 7// 向远离0的方向取整,因为随目标属性值与当前属性值接近// speed趋近于零点几,此时如果向靠近0的方向取整,// 虽然看似效果达到了但会引发一个问题。// 比如说speed = 0.1时,同时当前属性值与目标属性值还不相等时,// Math.floor(speed) = 0,dom.style[attr] = iCur + 0 + 'px',// 当前属性值与目标属性值永远不会相等// 也就是说下面的锁会不关,导致dom中的定时器一直运行,占用内存。speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed)// 分别对透明度和其他样式进行改变if (attr == 'opacity'){// 改变透明度时要除以100使其重新变成小数dom.style.opacity = (iCur + speed) / 100}else{// 其他属性不要忘记加px拼接字符串dom.style[attr] = iCur + speed + 'px'}// 当前属性值不等于目标属性值时,关锁,使定时器继续工作if (iCur != attrObj[attr]) {bStop = false// console.log(1)}}// 一旦当前属性值等于目标属性值,bStop为true,锁开着,才能清除定时器if (bStop) {clearInterval(dom.timer)} },30)}</script>
</body>
</html>
设置4个div盒子,设置宽高,颜色及透明度,利用javascript使其宽高及透明度属性缓冲变化。实现过程注释里写的很清楚,这里只说一点:如果设置了锁,开锁和关锁的条件需仔细斟酌,要不然可能会出现该开的时候不开,该关的时候关不上的情况。此例需要注意的地方就是缓冲速度speed的取整问题,向远离0的方向取整才能恰当地关锁,清除定时器。