首页 > 技术文章 > 延时提示框制作思路[简单javascript案例]

f6056 2018-07-06 17:56 原文

模拟QQ软件中的弹出提示框功能,制作一个简易的延时提示框。
功能实现:
1、当鼠标移入指定区块时,弹出隐藏的区块;当鼠标移出指定区块时,弹出的隐藏区块再次隐藏。
2、同时要求在鼠标移入该弹出区块后,区块继续保持显示状态,在鼠标移出弹出区块后,弹出的隐藏区块再次隐藏。
主要应用知识:setTimeout()函数、clearTimeout()以及连等应用。
初始的HTML代码:
 
<div id="div1" ></div>
<div id="div2" ></div>

  

以及相应的内置样式表:
div{
	float:left;
	margin:10px;
	}
#div1{
	width:50px;
	height:50px;
	background:red;
	}
#div2{
	width:250px;
	height:180px;
	background:#ccc;
	display:none;
	}

  

构建一个window.onload函数,所有JS代码均在该函数内。同时获取相应的div元素。

window.onload=function()
{
	var oDiv1=document.getElementById("div1");
	var oDiv2=document.getElementById("div2");     			
};

 

  

设计目标:[当鼠标移入指定区块时,弹出隐藏的区块;当鼠标移出指定区块时,弹出的隐藏区块再次隐藏。]
初步编写JavaScript函数代码:

 1     oDiv1.onmouseover=function()
 2     {
 3         oDiv2.style.display="block";
 4     }
 5     //当鼠标移入oDiv1时,oDiv2显示
 6     oDiv1.onmouseout=function()
 7     {
 8         oDiv2.style.display="none";
 9     }
10     //当鼠标移出oDiv1时,oDiv2消失
设计目标:[在鼠标移入该弹出区块后,区块继续保持显示状态,在鼠标移出弹出区块后,弹出的隐藏区块再次隐藏。]
初步编写JavaScript函数代码:

 1    oDiv2.onmouseover=function()
 2     {
 3         oDiv2.style.display="block";
 4     }
 5     //当鼠标移入oDiv2时,oDiv2显示
 6     oDiv2.onmouseout=function()
 7     {
 8         oDiv2.style.display="none";
 9     }
10     //当鼠标移出oDiv2时,oDiv2消失

在浏览器中运行该代码发现问题:鼠标一旦离开oDiv1,即触发oDiv1.onmouseout这行代码执行,导致oDiv2区块display="none";,鼠标无法移到oDiv2上面。后续设计目标无法实现。setTimeout()函数用于解决这个问题,即在鼠标移出oDiv1后,需要令oDiv2继续显示一段时间,以供鼠标移入。
因此代码需要进行如下更改:

oDiv1.onmouseout=function()
    {
        oDiv2.style.display="none";
    }
    //当鼠标移出oDiv1时,oDiv2消失

更改为

oDiv1.onmouseout=function()
    {
        setTimeout(function()
        {
            oDiv2.style.display="none";
        }
        ,500);
    }
    //在鼠标移出oDiv1时,通过setTimeout()令oDiv2延迟0.5s消失
在浏览器中运行代码后发现问题:尽管通过setTimeout()令鼠标在移出oDiv1后oDiv2可以显示一段时间,但是鼠标移入oDiv2后,oDiv2仍然消失了。这是由于定时器的设置oDiv2.style.display="none";在0.5s后生效。
但是明明写了鼠标移入oDiv2后,区块显示的代码啊:
oDiv2.onmouseover=function()
    {
        oDiv2.style.display="block";
    }
    //当鼠标移入oDiv2时,oDiv2显示
再次尝试,发现问题仍然存在。这里setTimeout()中对于oDiv2的display设置代码优先级高于后添加的这段代码。逻辑:只有setTimeout()的代码正确执行,才能有触发oDiv2.onmouseover的条件。setTimeout()的中的代码是oDiv2.onmouseover中的代码执行的先决条件,两者冲突时,setTimeout()的中的代码优先。但是具体的JavaScript的执行语句出现冲突时,js是如何进行条件优先级判断的还不太明白。
设计目标:[在鼠标移入该弹出区块后,区块继续保持显示状态,在鼠标移出弹出区块后,弹出的隐藏区块再次隐藏。]
联合上段代码分解目标:[在鼠标移入该弹出区块后,定时器停止;鼠标移出弹出区块后,弹出的隐藏区块再次隐藏。]
对JavaScript代码再次编辑:
增加变量代码:
var timer=null;
赋值定时器的返回值:
oDiv1.onmouseout=function()
    {
        timer=setTimeout(function()
        {
            oDiv2.style.display="none";
        }
        ,500);
    }
当鼠标移入oDiv2模块时,oDiv显示并且停止定时器

 oDiv2.onmouseover=function()
    {
        oDiv2.style.display="block";
                clearTimeout(timer);          
    }
至此,模拟延时提示框的的代码框架基本完工。不过还有几个细节方面可以进行优化。
 
1、当从oDiv2移动到oDiv1时,oDiv2会出现“闪一下”的现象,这是由于鼠标移出oDiv2,oDiv2立刻消失,而鼠标移入oDiv1时,oDiv再次立刻出现,两者时间间隔极短,故而出现oDiv2闪一下。

 

解决方案:
在鼠标移出oDiv2时,也添加一个延时设计的定时器。

oDiv2.onmouseout=function()
    {
        setTimeout(function()
        {
            oDiv2.style.display="none";
        }
        ,500);
    }
2、在反复多次快速鼠标移入移出后,浏览器似乎出现了“疲惫现象”,处于红色div1区块中,div2也不显示。但是缓慢移出后,再移入又恢复代码编写时的初始原设计目的。

 

猜测:应该属于代码逻辑性问题。
oDiv1.onmouseover 执行 oDiv2.style.display=block';
oDiv2.onmouseout[包括oDiv1.onmouseover的情形] oDiv2.style.display='none';
这样存在两个截然不同的逻辑结果?

 
3、观察JsvaScript代码,可以发现代码中存在相当多的类似代码。能否在不改变代码功能的前提下对代码进行精简处理呢?
window.onload=function()
{
    var oDiv1=document.getElementById("div1");
    var oDiv2=document.getElementById("div2");
    var timer=null;
    oDiv1.onmouseover=function()
    {
        oDiv2.style.display="block";
    }
    //当鼠标移入oDiv1时,oDiv2显示
    
    oDiv1.onmouseout=function()
    {
        timer=setTimeout(function()
        {
            oDiv2.style.display="none";
        }
        ,500);
    }
    //在鼠标移出oDiv1时,通过setTimeout()令oDiv2延迟0.5s消失
    
    oDiv2.onmouseover=function()
    {
        oDiv2.style.display="block";
        clearTimeout(timer);
    }
    //当鼠标移入oDiv2时,oDiv2显示
    oDiv2.onmouseout=function()
    {
        setTimeout(function()
        {
            oDiv2.style.display="none";
        }
        ,500);
    }

                 
};
代码精简合并处理:

oDiv1.onmouseout=function()
    {
        timer=setTimeout(function()
        {
            oDiv2.style.display="none";
        }
        ,500);
    }

oDiv2.onmouseout=function()
    {
        setTimeout(function()
        {
            oDiv2.style.display="none";
        }
        ,500);
    }
合并处理

oDiv1.onmouseout=oDiv2.onmouseout=function()
    {
        timer=setTimeout(function()
        {
            oDiv2.style.display="none";
        }
        ,500);
    }

代码

oDiv1.onmouseover=function()
    {
        oDiv2.style.display="block";
    }

oDiv2.onmouseover=function()
    {
        oDiv2.style.display="block";
        clearTimeout(timer);
    }

合并处理

oDiv1.onmouseover=oDiv2.onmouseover=function()
    {
        oDiv2.style.display="block";
                clearTimeout(timer);
    }
最终优化的JavaScript代码为
window.onload=function()
{
    var oDiv1=document.getElementById("div1");
    var oDiv2=document.getElementById("div2");
    var timer=null;    
    oDiv1.onmouseout=oDiv2.onmouseout=function()
    {
        timer=setTimeout(function()
        {
            oDiv2.style.display="none";
        }
        ,500);
    }
    
    oDiv2.onmouseover=oDiv1.onmouseover=function()
    {
        oDiv2.style.display="block";
        clearTimeout(timer);
    }
                 
};