想用原生JS 写个渐渐显示 一秒后渐渐隐藏的特效 但问题百出 而且点第二次后会,,,, 可以console.log看
不会JS 所以请教JS大神 帮忙看看 到底哪里出了问题
测试 http://mlloo.cn/test.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>JS弹出DIV层</title>
<script type="text/javascript">
var i = 0;
function emotion() {
var oMenu = document.getElementById("menu");
//渐现
fnLarge();
//一秒后渐隐
setTimeout("fnSmall()", 1000);
}
//渐现
function fnLarge() {
var oMenu = document.getElementById("menu");
oMenu.style.display = "block";
if(i < 1){
i += 0.1;
//console.log();
oMenu.style.opacity = i;
setTimeout("fnLarge()", 100);
}
}
//渐隐
function fnSmall() {
var oMenu = document.getElementById("menu");
var i=oMenu.style.opacity;
console.log(i);
if (i > 0.1) {
i -= 0.1;
oMenu.style.opacity = i;
setTimeout("fnSmall()", 100);
} else {
oMenu.style.opacity=0;
oMenu.style.display = "none";
}
}
</script>
<style type="text/css">
body {
text-align: center;
}
#menu {
width: 50px;
height: 50px;
border: 1px solid #666;
background: #fff;
margin: 5px auto;
overflow: hidden;
display: none;
padding: 5px 10px;
}
</style>
</head>
<body>
<p onclick="emotion();">点击这行文字试试!</p>
<div id="menu"></div>
</body>
</html>
在你第一次点击完了之后i的值是0.1,在函数fnSmall()里面有判断i是大于0.1的,问题出在这里
代码存在很多毛病
1.状态维护错误,i和opacity应该同时变化,但代码中有的地方i和opactiy没有同时设置,导致两者数据不一致
2.存在多个定时器,未对定时器进行同步,导致竞争条件,导致结束状态不确定。
最简单的修改方案是每次点击时重置应用状态
function reset(){
i = 0;
var oMenu = document.getElementById("menu");
oMenu.style.opacity = 0
}
function emotion() {
reset()
var oMenu = document.getElementById("menu");
//渐现
fnLarge();
//一秒后渐隐
setTimeout("fnSmall()", 1000);
}
几点:1、你用console.log()跟踪一下fnLarge里面的i值就知道问题在哪里了。
2、明明css3的transition和animation那么好用,为什么还非要写js?
@sirqiao 是正确的,你的Fnlarge里的i值作用范围为整个<script>而fnsmall里的i值作用范围为fnsamll函数。所以当全局的i值在fnlarge里增加后,fnsamll并未将此i值减小,导致第二次点击时,Fnlarge里的i值仍等于1。
同时计时器部分感觉不太好,假如后期想渐渐显示2s后渐渐隐藏,要改的地方就多了。不如将fnsamll作为fnlarge跳出循环后的返回函数。
而fnsamll里omenu的display:none应该删除。