Javascript Chrome在基础元素上的奇怪单击行为

Javascript Chrome在基础元素上的奇怪单击行为,javascript,Javascript,我有下面的HTML代码。当屏幕被“cover”DIV覆盖时,单击按钮和其他地方。单击按钮上的“不”不会触发。稍后,当“cover”DIV被隐藏时,单击按钮将触发 似乎有时间问题。有人能解释一下这种行为吗 标记: <div id="cover"></div> <button onclick="alert('Button clicked')">Click me</button> <div id="text"></div>​ #

我有下面的HTML代码。当屏幕被“cover”DIV覆盖时,单击按钮和其他地方。单击按钮上的“不”不会触发。稍后,当“cover”DIV被隐藏时,单击按钮将触发

似乎有时间问题。有人能解释一下这种行为吗

标记:

<div id="cover"></div>
<button onclick="alert('Button clicked')">Click me</button>
<div id="text"></div>​
#cover {
    display: none;
    position: fixed;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    z-index: 100;
    background-color: white;
    opacity: 0.8
}​
function hide ()
{
    document.getElementById ("cover").style.display = "none";
}
function show ()
{
    document.getElementById ("cover").style.display = "block";
}
function busy (callback)
{
    show ();
    setTimeout (callback, 1);
}
function work ()
{
    var start = (new Date ()).getTime ();
    var wait  = 3000;
    while ((new Date()).getTime () - start < wait)
    {
        /* do nothing */
    }
    hide ();
}
function start ()
{
    document.getElementById ("cover").onclick = function (ev) {
        document.getElementById ("text").innerHTML = 'Cover clicked';
    };
    busy (work);
}​
Javascript:

<div id="cover"></div>
<button onclick="alert('Button clicked')">Click me</button>
<div id="text"></div>​
#cover {
    display: none;
    position: fixed;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    z-index: 100;
    background-color: white;
    opacity: 0.8
}​
function hide ()
{
    document.getElementById ("cover").style.display = "none";
}
function show ()
{
    document.getElementById ("cover").style.display = "block";
}
function busy (callback)
{
    show ();
    setTimeout (callback, 1);
}
function work ()
{
    var start = (new Date ()).getTime ();
    var wait  = 3000;
    while ((new Date()).getTime () - start < wait)
    {
        /* do nothing */
    }
    hide ();
}
function start ()
{
    document.getElementById ("cover").onclick = function (ev) {
        document.getElementById ("text").innerHTML = 'Cover clicked';
    };
    busy (work);
}​
函数隐藏()
{
document.getElementById(“封面”).style.display=“无”;
}
函数显示()
{
document.getElementById(“cover”).style.display=“block”;
}
函数忙(回调)
{
show();
setTimeout(回调,1);
}
功能工作()
{
var start=(新日期()).getTime();
var-wait=3000;
while((new Date()).getTime()-start

您的
工作
功能不起作用(没有双关语):它会将UI冻结3秒钟,因此单击和其他交互将按照您的描述排队。为什么不直接将
3000
传递到
setTimeout
而不是
1

function busy (callback)
{
    show ();
    setTimeout (callback, 3000);
}
function work ()
{
    hide ();
}

您的
work
功能不起作用(没有双关语):它会将UI冻结3秒钟,因此单击和其他交互将按照您的描述排队。为什么不直接将
3000
传递到
setTimeout
而不是
1

function busy (callback)
{
    show ();
    setTimeout (callback, 3000);
}
function work ()
{
    hide ();
}

发生这种情况是因为您正在锁定页面线程:

while ((new Date()).getTime () - start < wait)
{
    /* do nothing */
}
while((新日期()).getTime()-start
这将防止在事件完成之前处理事件,并防止对UI进行更新


为什么不干脆用超时来代替呢<代码>设置超时(隐藏、等待)

发生这种情况是因为您正在锁定页面线程:

while ((new Date()).getTime () - start < wait)
{
    /* do nothing */
}
while((新日期()).getTime()-start
这将防止在事件完成之前处理事件,并防止对UI进行更新


为什么不干脆用超时来代替呢<代码>设置超时(隐藏、等待)

经过多次测试,我可以确认此行为。Firefox和Chrome有很大的区别

请记住,正如许多人所说,Javascript程序是单线程的

在Firefox中,当函数“work”执行Ajax调用时,单击被忽略。当函数返回且“cover”消失时,不会发生任何事情

在Chrome中,点击被捕获并排队。当函数“work”返回时,将触发onclick事件。由于“cover”已消失,因此它不会获得onclick事件。另一方面,按钮接收onclick事件。例如,当我点击按钮两次(当它被覆盖时),之后我会收到两个警报

我发现Chrome的行为令人困惑,而且我错了,因为当我点击时,我的眼睛自然会告诉我按钮被覆盖,因此无法点击(它不会显示为点击按钮)


谢谢你提供的所有答案和线索。非常感谢。

经过多次测试,我可以确认这种行为。Firefox和Chrome有很大的区别

请记住,正如许多人所说,Javascript程序是单线程的

在Firefox中,当函数“work”执行Ajax调用时,单击被忽略。当函数返回且“cover”消失时,不会发生任何事情

在Chrome中,点击被捕获并排队。当函数“work”返回时,将触发onclick事件。由于“cover”已消失,因此它不会获得onclick事件。另一方面,按钮接收onclick事件。例如,当我点击按钮两次(当它被覆盖时),之后我会收到两个警报

我发现Chrome的行为令人困惑,而且我错了,因为当我点击时,我的眼睛自然会告诉我按钮被覆盖,因此无法点击(它不会显示为点击按钮)


谢谢你提供的所有答案和线索。我真的很感激。

我想这是为了(模拟一些长时间运行的脚本),因为他已经在其他函数中使用了setTimeout。但确实,整个脚本都是在一个线程中处理的,所以长时间运行的计算会降低页面的响应速度。如果可以的话,将这些函数拆分成更小的块,并使用
setTimeout(callback,0)
允许浏览器处理堆叠的事件。@skalee一个很好的建议。如果这真的是OP试图解决的问题,那么可能也值得研究一下。实际上,延迟是由我的服务器通过使用Ajax(函数“work”执行对服务器的Ajax调用)而不是Javascript代码完成的。行为还是一样的。为什么当我们在封面后面看到按钮时,点击会穿过按钮呢。“我们所看到的和所做的之间不是有点不一致吗?”马尔克。我无法重现您描述的问题(参见更新的fiddle with changed work and busy functions-)。当我第一次单击按钮并且封面可见时,我只看到“cover clicked”(封面已单击)消息。您更改了“work”(工作)函数,它可以工作,但实际上此函数对服务器执行Ajax调用,延迟由服务器完成。我也为提到Chrome而道歉。我在Chromium20.0、Firefox17.0.1和IPad2上的Safari上测试了它。结果都是一样的,我想这是为了(模拟一些长时间运行的脚本),因为他已经在其他函数中使用了setTimeout。但确实,整个脚本都是在一个线程中处理的,所以长时间运行的计算会降低页面的响应速度。如果可以的话,将这些函数拆分成更小的块,并使用
setTimeout(callback,0)
允许浏览器处理堆叠的事件。@skalee一个很好的建议。如果这真的是问题所在的话,OP正试图解决