Javascript 为什么window.setTimeout(someFunc,0)与直接调用someFunc不同?

Javascript 为什么window.setTimeout(someFunc,0)与直接调用someFunc不同?,javascript,drop-down-menu,Javascript,Drop Down Menu,我正在尝试在我的网页中使用JS实现一个下拉菜单。我知道这在CSS中是可能的,但我仍然希望使用JS来实现这一点 所以我在谷歌上搜索了一下,找到了以下代码: var超时=500; var closetimer=0; var ddmenuitem=0; //打开隐藏层 功能mopen(id) { //取消关闭计时器 McCancelCloseTime(); //封闭旧层 if(ddmenuitem)ddmenuitem.style.visibility='hidden'; //获取新图层并显示它

我正在尝试在我的网页中使用JS实现一个下拉菜单。我知道这在CSS中是可能的,但我仍然希望使用JS来实现这一点

所以我在谷歌上搜索了一下,找到了以下代码:

var超时=500;
var closetimer=0;
var ddmenuitem=0;
//打开隐藏层
功能mopen(id)
{   
//取消关闭计时器
McCancelCloseTime();
//封闭旧层
if(ddmenuitem)ddmenuitem.style.visibility='hidden';
//获取新图层并显示它
ddmenuitem=document.getElementById(id);
ddmenuitem.style.visibility='visible';
}
//近显示层
函数mclose()
{
if(ddmenuitem)ddmenuitem.style.visibility='hidden';
}
函数mclosetime()
{
closetimer=window.setTimeout(mclose,timeout);
}
//取消关闭计时器
函数mcancelclosetime()
{
if(关闭计时器)
{
清除超时(关闭计时器);
closetimer=null;
}
}
//单击“退出”时关闭图层
document.onclick=mclose;
#sddm
{边距:0;
填充:0;
z-指数:30}
#李淑仪
{边距:0;
填充:0;
列表样式:无;
浮动:左;
字体:粗体11px arial}
#李安
{显示:块;
边距:0 1px 0;
填充:4px10px;
宽度:60px;
背景#5970B2;
颜色:#FFF;
文本对齐:居中;
文本装饰:无}
#李安:悬停
{背景:#49A3FF}
#sddm部门
{位置:绝对位置;
可见性:隐藏;
保证金:0;
填充:0;
背景:#EAEBD8;
边框:1px实心#5970B2}
#sddm部门a
{位置:相对位置;
显示:块;
保证金:0;
填充物:5px10px;
宽度:自动;
空白:nowrap;
文本对齐:左对齐;
文字装饰:无;
背景:#EAEBD8;
颜色:#2875DE;
字体:11px arial}
#sddm分区a:悬停
{背景:#49A3FF;
颜色:#FFF}
我编辑了一点JS,因为我希望在鼠标指针移出下拉列表后,下拉列表立即消失。所以我把它改成:

function mclosetime()
{
    closetimer = window.setTimeout(mclose, 0);
}
并删除了
timeout
变量。一切仍然有效。然后我意识到
mclosetime
基本上调用
mclose
,延迟为0。我认为
mclosetime
是一个功能不多,可以删除的函数。因此,我删除了它并将
li
元素更改为直接调用
mclose

    <li><a href="#" onmouseover="mopen('m1')" onmouseout="mclose()">Home</a>
        <div id="m1" onmouseover="mcancelclosetime()" onmouseout="mclose()">
        <a href="#">HTML DropDown</a>
        <a href="#">DHTML DropDown menu</a>
        <a href="#">JavaScript DropDown</a>
        <a href="#">DropDown Menu</a>
        <a href="#">CSS DropDown</a>
        </div>
    </li>
同样的事情还是发生了


我真的很困惑。不
window.setTimeout
如果超时为0,只调用函数?如果它没有做更多的事情,那么在这里调用
mclose
应该可以

setTimout
异步工作。这意味着,一旦当前调用堆栈完成执行,它将排队运行
mclose
。如果直接调用
mclose
,它将按顺序(同步)在当前调用堆栈中执行,但
setTimout
会在下一个调用堆栈中立即执行

setTimeout(myFun,0)
无法保证
myFun
会立即被调用


在钩子下,当您执行
window.setTimeout(myFun,0)
时,浏览器只会将函数
myFun
放入浏览器事件队列。只有当队列中没有其他内容时,浏览器才会立即执行它。因此,如果队列中存在某些内容,它将在您的
myFun

之前执行。您的setTimeout函数没有问题。问题在于JavaScript的
mouse out
事件,它也应用于嵌套的子元素。一旦将鼠标移到子DIV上,就会触发父DIV的mouse out事件JQuery通过使用它的
mouseleave
事件提供了一个解决此问题的简单方法,该事件正好满足您的需要


从技术上讲,
setTimeout(func,delay)
意味着在不少于
delay
ms的时间内调用
func
,而不完全是在
delay
ms之后。@路人为什么会有不同?另外,你能给我文档的链接吗?我读了关于W3Schools的
setTimeout
页面,它似乎没有提到这一点。请阅读,尤其是“注释”部分。我现在明白了!正是这种延迟导致稍后调用
mclose
。在此延迟期间,我的鼠标移动到下拉菜单,超时被取消。
function mclose()
{
    closetimer = 1;
    if(ddmenuitem) ddmenuitem.style.visibility = 'hidden';
}