打开QQ,把鼠标放在你的头像上不动,会弹出你一个框展示你的个人信息,这个框就是延时提示框,它不像:hover,鼠标离开后立即消失,而是在短暂的延迟后才消失,这个看似简单的小效果,在实际中用的非常多,而且其中的一些小细节也是值得揣摩的。
实现效果
原理分析
- 用display属性控制div的显隐。
- 用setTimeout()来控制延迟。
代码分析
<style>
div{ float: left; margin-left: 20px; }
#div1{ width: 50px; height: 50px; background: red; }
#div2{ width: 250px; height: 180px; background: #CCC; }
</style>
<body>
<div id="div1"></div>
<div id="div2"></div>
</body>
最简单的控制div显隐。
window.onload = function (){
var oDiv1 = document.getElementById('div1');
var oDiv2 = document.getElementById('div2');
oDiv1.onmouseover = function (){
oDiv2.style.display = "block";
};
oDiv1.onmouseout = function (){
oDiv2.style.display = "none";
};
};
但是这样有个问题,鼠标一移出div1,div2就消失了,鼠标永远也到不了div2上,为了解决这个问题,我们给鼠标移出加上定时器。
oDiv1.onmouseover = function (){
oDiv2.style.display = "block";
};
oDiv1.onmouseout = function (){
setTimeout(function (){
oDiv2.style.display = "none";
}, 800);
};
现在因为有延迟的存在,鼠标可以移到div2上了,但是延迟一过,div2还是得消失,所以我们得给div2加上鼠标移入事件:鼠标移入div2时,display = "block"。
oDiv2.onmouseover = function (){
oDiv2.style.display = "block";
};
打开浏览器试试,发现还是不行,延迟一过,div2还是消失了,怎么回事?因为setTimeout()就像一个定时炸弹一样,时间一到,该消失还是得消失,所以我们必须得在鼠标移入时关闭定时器,通常我们会声明一个timer用来存放定时器。
window.onload = function (){
var oDiv1 = document.getElementById("div1");
var oDiv2 = document.getElementById("div2");
var timer = null;
oDiv1.onmouseover = function (){
oDiv2.style.display = "block";
};
oDiv1.onmouseout = function (){
timer = setTimeout(function (){
oDiv2.style.display = "none";
}, 500);
};
oDiv2.onmouseover = function(){
clearTimeout(timer);
oDiv2.style.display = "block";
};
};
这下总行了吧?其实有经验的同学应该能看出来,这样鼠标确实能移入div2了,但是从div2移出后div2并不会消失,因为没有移出事件,移出时应该把div2的display改为none,并且也应该加上定时器,同时,根据以往的经验,移出时加了定时器,在移入是应该关闭定时器,要不然鼠标回到div1时div2又消失了,而实际的效果应该是不论鼠标在div1上还是在div2上,div2都应该显示的,所以我们可以在每次鼠标移入div1时都先关闭定时器。
var timer=null;
oDiv1.onmouseover = function (){
clearTimeout(timer);
oDiv2.style.display = "block";
};
oDiv1.onmouseout = function (){
timer = setTimeout(function (){
oDiv2.style.display = "none";
}, 800);
};
oDiv2.onmouseover = function (){
oDiv2.style.display = "block";
clearTimeout(timer);
};
oDiv2.onmouseout = function (){
timer = setTimeout(function (){
oDiv2.style.display = "none";
}, 800);
};
至此,我们的延时提示框已经完成了,没有bug。但是!我们仔细看看代码,有没有发现好像两个div的移入事件一样,移出事件也一样啊。伟大的党曾教导我们,代码能简化的要简化,写出的代码要优雅。so,我们简化合并一下。
window.onload = function (){
var oDiv1 = document.getElementById("div1");
var oDiv2 = document.getElementById("div2");
var timer = null;
oDiv2.onmouseover = oDiv1.onmouseover = function (){
clearTimeout(timer);
oDiv2.style.display = "block";
};
oDiv2.onmouseout = oDiv1.onmouseout = function (){
timer = setTimeout(function (){
oDiv2.style.display = "none";
}, 800);
};
};
分析总结
js中是可以用连等的,能用就用,代码将简化不少。
一开始总会想当然地把程序想简单,可是一测试才知道少这少那,这是大家年轻时候的通病。也许是经历的多了,那些老师们、大神们无论面对看起来多么简单的问题都会严谨的分析,一丝不苟,这种态度,让我惭愧的同时,也让我感受到了一点作为程序员的情怀。