<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
div {
width: 100px;
height: 50px;
background: blue;
margin: 10px;
}
</style>
<script>
window.onload = function () {
let aDiv = document.getElementsByTagName('div');
for (let i = 0; i < aDiv.length; i++) {
aDiv[i].timer = null;
aDiv[i].onmouseover = function () {
startMove(this, 400);
};
aDiv[i].onmouseout = function () {
startMove(this,100);
}
}
};
function startMove(obj, iTarget) {
clearInterval(obj.timer);
obj.timer = setInterval(function () {
let speed = (iTarget - obj.offsetWidth) / 6;
speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
if (obj.offsetWidth === iTarget) {
clearInterval(timer);
}
else {
obj.style.width = obj.offsetWidth + speed + 'px';
}
}, 30)
}
</script>
</head>
<body>
<div></div>
<div></div>
<div></div>
</body>
</html>
以上代码在页面中显示3个蓝色div,当鼠标在div上时触发mouseover事件,div宽度由100px运动到400px。当鼠标移开时触发mouseout事件,width运动回100px。
let speed = (iTarget - obj.offsetWidth) / 6; 除6起到缓冲的作用,当width接近设定时速度减小,视觉效果更好233。
与之前几个代码不同的是这次创建了aDiv.timer属性用来存储定时器,也就是每个div都有自己的定时器,防止只有一个定时器时,当鼠标离开div甲 进入div乙时,div甲的width不能回到100px(div甲的width还没减小到100px,timer就被div乙拿去用了)的情况。
添加边框和淡化效果
鼠标在Div上时Div从透明变成不透明,鼠标移开后再变回去。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
div {
width: 100px;
height: 50px;
background: blue;
margin: 10px;
border: 10px solid black;
opacity: 0.3;
}
</style>
<script>
function getStyle(obj, name) {
if (obj.currentStyle) {
return obj.currentStyle
}
else {
return getComputedStyle(obj, null)[name]
}
}
window.onload = function () {
let aDiv = document.getElementsByTagName('div');
for (let i = 0; i < aDiv.length; i++) {
aDiv[i].timer = null;
aDiv[i].timer2 = null;
aDiv[i].onmouseover = function () {
startMove(this, 400);
changeOpacity(this, 1);
};
aDiv[i].onmouseout = function () {
startMove(this, 100);
changeOpacity(this, 0.3);
}
}
};
function startMove(obj, iTarget) {
clearInterval(obj.timer);
obj.timer = setInterval(function () {
let speed = (iTarget - parseInt(getStyle(obj, 'width'))) / 6;
speed = speed > 0 ? Math.ceil(speed) : Math.floor(speed);
if (obj.style.width === iTarget) {
clearInterval(obj.timer);
}
else {
obj.style.width = parseInt(getStyle(obj, 'width')) + speed + 'px';
}
}, 30)
}
function changeOpacity(obj, iTarget) {
clearInterval(obj.timer2);
obj.timer2 = setInterval(function () {
let speed = (iTarget*10 - getStyle(obj, 'opacity')*10);
console.log(speed);
speed = speed > 0 ? 1 : -1;
if (getStyle(obj,'opacity')*10 === iTarget*10) {
clearInterval(obj.timer2);
console.log('close!');
}
else {
obj.style.opacity = Math.round(getStyle(obj,'opacity')*10+speed)/10
}
}, 30)
}
</script>
</head>
<body>
<div></div>
<div></div>
<div></div>
</body>
</html>
添加边框border后就不能再用offsetWidth了。因为offsetwidth包含了padding和border,也就是整个盒子模型的宽度。我们要取的只是style 里的 width,这就要利用getStyle函数。getStyle里的判断语句用于兼容处理,IE 用 obj.currentStyle、Chrome和FireFox用getComputedStyle(obj, null)[name]。
淡化效果比较乱,因为计算机的存储方式的问题,例如直接执行
console.log(0.3-0.2)
就会发现输出不是0.1,而是0.09999999999999998(不同浏览器可能是其他数字)。
而透明度opacity的数值范围是0~1,涉及了小数运算。为了保证不出错,最好先换成整数计算,最后赋值再变回小数。
Math.round(X)就是将X四舍五入,返回整数。
在IE8及以前的版本中设置透明度要用filter:Alpha(opacity=50)。