JavaScript 以错误的顺序执行

标签 javascript jquery greasemonkey

我必须使用带有 select 元素的网站(票务系统),该元素当前包含 9994 个选项。这是不可更改的,必须按原样接受。

当我在该网站上处理票证时,我必须从该选择中选择一个特定条目。我总共有大约 30 个条目可供选择。我不关心其他条目。

RegEx 过滤器所需的 30 个条目可以分为 3 种模式。

所以我决定使用 Greasemonkey+JQuery 来清理该选择元素,这样我就可以轻松快速地找到我要查找的条目。

过滤工作正常,但需要时间(当然需要时间...),所以我想在过滤器运行时显示一些“请稍候”div 作为叠加层以提供某种用户反馈.


在页面加载时,我创建叠加层:

$("body").append('<div id="pleaseWaitOverlay" style="position: fixed; top: 0; left: 0; bottom: 0; right: 0; background-color: rgb(255,255,255);">HALLO WELT</div>');
$("#pleaseWaitOverlay").hide();

//This is the select element with the "few" entries
fixedInReleaseElement = $('select[name=resolvedReleasePath]');

//Adding buttons to filter for one of the patterns are also added on page load

如果我按下其中一个过滤器按钮,将调用以下函数:

function filterFixedInReleaseList(filterFor) {
    $("#pleaseWaitOverlay").show();
    //$("#pleaseWaitOverlay").show().delay(500).show(); - or as hack without success...

    var pattern;

    //Based on "filterFor" parameter, the required pattern will be used.
    // [MORE CODE]

    fixedInReleaseElement.find("option").each(function() {
        var currentOption = $(this);
        if (pattern === "") {
            currentOption.show();
        }
        else {
            if (pattern.test(currentOption.text())) {
                currentOption.show();
            }
            else {
                currentOption.hide();
            }
        }
    });

    //$("#pleaseWaitOverlay").hide();
}

但不知何故,过滤器将会发生,然后叠加层将会显示。

请注意:

  • 目前,.hide() 行已被注释掉,因为执行这些行时根本不会显示(或者更确切地说是看到)弹出窗口。
  • .show().delay(500).show() 是一种破解它的尝试,但它绝对没有改变任何东西。 我也尝试过fixedInReleaseElement.find("option").delay(1000).each()但没有成功。我觉得延迟根本不起作用?

那么,这里有什么问题呢?为什么执行过滤器后会显示叠加层?

完整的 Greasemonkey 脚本可以在这里找到: http://pastebin.com/auafMSR1

最佳答案

浏览器选项卡只有一个线程,在 JavaScript 和 UI 更新之间共享。因此,如果您的 JavaScript 正在运行,则 UI 不会更新。

所以,这个:

function doSomethingLongWithOverlayWrongly() {
  $x.show();
  doSomethingLong();
  $x.hide();
}

将把$x的适当属性设置为隐藏,然后做一些长的事情,然后将属性设置回来;当 doSomethingLongWithOverlayWrongly(以及 future 的所有计算)最终退出并放弃对执行线程的控制时,浏览器将注意到某些属性已更改,并在必要时重新绘制(但不是,因为该元素已设置为不可见,并且现在仍设置为不可见)。

这样做:

function doSomethingLongWithOverlayCorrectly() {
  $x.show();
  setTimeout(function() {
    doSomethingLong();
    $x.hide();
  }, 0);
}

这会将 $x 设置为隐藏,然后安排超时,然后退出。浏览器进行查看,发现重绘已就绪,并显示您的叠加层。然后超时的函数开始运行,执行一些长时间的操作,并将 $x 设置为再次隐藏。当它退出时,浏览器会再看一眼,发现需要重新绘制,并隐藏您的覆盖层。

关于JavaScript 以错误的顺序执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29228661/

相关文章:

javascript - Greasemonkey 显示警报一次

javascript - Jquery Unobtrusive 验证不适用于 View 模型列表中第一个之后的项目 - c# MVC 4

javascript - 将 javascript 参数传递到 D3

javascript - 图例颜色不适用于 ChartJS 饼图中随机生成的背景颜色

javascript - 正文背景位置必须相对于页面元素

javascript - 将 jQueryUI 对话框中的 <p> 重新定位到 CSS 打印的中心位置

javascript - 从文本中删除 <b> 标记

javascript - 将 Circles 和 Path 分组为 D3 Force Layout 中的节点?

javascript - 如何同时使用 onclick 和目标 ="_blank"

javascript - Greasemonkey 脚本将一个元素移动到另一个元素?