jQuery 移动弹出窗口 open/close 直到功能结束才触发

jQuery Mobile popup open/close is not firing until end of function

我有一个 jQuery 移动 (jQM) 单页应用程序 (SPA)。我试图在一个可能很长的 运行 过程中显示一个弹出窗口。在 cleanUp 函数终止之前,弹出窗口 open/close 不会工作。因此,我当时得到了一个简短的弹出窗口,所以至少它是有效的。较大的应用程序也在工作,但不是这个特定的清理功能。

我试过在打开之前包含一个 popup() 初始化。我还尝试在每个弹出窗口周围使用 setTimeout 包装器。虽然我使用 Sprockets 构建应用程序,但我在页面创建后手动将清理代码迁移到主体中。我一直无法打开弹出窗口,然后在关闭时关闭。

此应用程序非常复杂,因此我尝试针对此问题提取有问题的 jQM 应用程序。由于它是一个 SPA,HTML 文件中包含多个逻辑页面。每个 cleanUp 弹出窗口都包含在 div 之后,data-role="main"。有问题的弹出窗口包含在每个逻辑页面上,具有相同的 HTML ID,因此在一个物理 HTML 页面中包含多次。 jQM 旨在适当地管理这个问题,因为 jQM 的处理实际上需要它,因为它在一个物理页面中维护旧逻辑页面和新逻辑页面的副本以支持页面转换。

这是jQM提取。 HTML 也可以从这段代码中推断出来。

let triggered;
const oneMinute = 60 * 1000;
const oneSecond = 1000;

$(function ($, window, document) {

    $("body").pagecontainer({
        defaults: false
    });
    $(":mobile-pagecontainer").on("pagecreate", "#pageone", function (event, ui) {

            function delay(seconds) {
                for (let count = 0; count < seconds; count++) {
                    let _currentTime = new Date().getTime();
                    while (_currentTime + oneSecond >= new Date().getTime()) {
                    }
                }
            }

            let cleanUpTimer;

            function setCleanUpTimer(seconds) {
                return cleanUpTimer = setTimeout(function () {
                    cleanUp();
                }, seconds * oneSecond)
            }

            function clearCleanUpTimer(timer) {
                return clearTimeout(timer)
            }

            function cleanUp() {
                clearCleanUpTimer(cleanUpTimer);
                let _page = $(":mobile-pagecontainer").pagecontainer('getActivePage')[0].id;
                if (_page !== "") {
                    // id=cleanUpMessage is included in each jQm 'div <data-role=page...>', which means several/many are included within the HTML page.
                    $(":mobile-pagecontainer").pagecontainer('getActivePage').find("#cleanUpMessage").popup("open");
                    console.log("Clean up fired.");
                    delay(10);
                    // Problem: #cleanUpMessage doesn't display until the following command && doesn't clear until after function return
                    $(":mobile-pagecontainer").pagecontainer('getActivePage').find("#cleanUpMessage").popup("close");
                    console.log("Clean up ended.");
                }
                setCleanUpTimer(10);
                return false;
            }

            // pagecreate fires on every page change, even AJAX changes

            // This stabilizer prevents disruption of the jQM environment on changes
            if (triggered === undefined) {
                triggered = true;

                cleanUp();

            } // stabilzer end
        }
    ) // pagecreate end

}(window.jQuery, window, document)); // function end

弹窗是_cleanup.html:

<div data-role="popup" id="cleanUpMessage">
  <p>Please wait while clean up is in process.
</div>

逻辑页面的示例如下,其中 _cleanup.html 包含 frontend/cleanup.html"

的弹出窗口
<div data-theme="a" data-role="page" id="anchor_page">
  <%= partial :'frontend/header.html', locals: {page: 'Anchor Page'} %>
  <div data-role="main" class="ui-content">
    <%= partial :'frontend/cleanup.html' %>
    <p>This is the last page.
  </div>
  <%= partial :'main-footer.html' %>
</div>

注意:这是一个 Ruby/Sinatra/Rack Middleware/WebSockets 应用程序。使用 Sinatra-Partial gem.

支持分音

更新:修改清理以尝试使用 afteropen。在这种情况下,弹出窗口和回调都不会触发。

    function cleanUp() {
        clearCleanUpTimer(cleanUpTimer);
        let _page = $(":mobile-pagecontainer").pagecontainer('getActivePage')[0].id;
        if (_page !== "") {
            // id=cleanUpMessage is included in each jQm 'div <data-role=page...>', which means several/many are included within the HTML page.
            $(":mobile-pagecontainer").pagecontainer('getActivePage').find("#cleanUpMessage").popup({
                afteropen: function (event, ui) {
                    console.log("Clean up fired.");
                    delay(10);
                    // Problem: #cleanUpMessage doesn't display until the following command && doesn't clear until after function return
                    //$(":mobile-pagecontainer").pagecontainer('getActivePage').find("#cleanUpMessage").popup("close");
                    console.log("Clean up ended.");
                }
            });
        }
        setCleanUpTimer(10);
    }

这很奇怪,但经过几次(十几个)排列后,我找到了一个可行的方法。我遇到的问题是我似乎无法在同一功能中触发弹出窗口并清除它。我在 cleanUpStart 中启动 cleanUp 函数,然后使用 setTimeout 关闭 cleanUpProcess。它有点乱,但它有效...

const oneMinute = 60 * 1000;
const oneSecond = 1000;
const pound = "#";

$(function ($, window, document) {

    $("body").pagecontainer({
        defaults: false
    });
    $(":mobile-pagecontainer").on("pagecreate", "#pageone", function (event, ui) {

            function delay(seconds) {
                let _currentTime = new Date().getTime();
                let _delay = seconds * oneSecond;
                while (_currentTime + _delay >= new Date().getTime()) {
                }
            }

            let cleanUpStartTimer;
            let cleanUpProcessTimer;

            function setCleanUpStartTimer(seconds) {
                return cleanUpStartTimer = setTimeout(function () {
                    cleanUpStart();
                }, seconds * oneSecond)
            }

            function clearCleanUpStartTimer(timer) {
                return clearTimeout(timer)
            }

            function cleanUpProcess() {
                console.log("Clean Up Processing");
                // Clean up process here;
                delay(3);
                console.log("Clean Up Processed");
            }

            function runCleanUpProcess(seconds, _page) {
                return cleanUpProcessTimer = setTimeout(function () {
                    if (_page !== "") {
                        cleanUpProcess();
                        $(document).one("pagechange", function (event) {
                            $("#cleanUpMessage").popup("close");
                            console.log("Clean Up Ended.");
                        });
                        $(document).pagecontainer("change", pound + _page);
                    }
                    setCleanUpStartTimer(10);
                }, seconds * oneSecond)
            }

            function cleanUpStart() {
                clearCleanUpStartTimer(cleanUpStartTimer);
                let _page = $("body").pagecontainer('getActivePage')[0].id;
                if (_page !== "") {
                    $(document).one("pagechange", function (event) {
                        $("#cleanUpMessage").popup("open");
                        console.log("Clean Up Fired.");
                    });
                    $(document).pagecontainer("change", pound + _page);
                }
                runCleanUpProcess(1, _page);
                return false;
            }

            if (theGlobals.triggered === undefined) {
                theGlobals.triggered = true;

                cleanUpStart();

            } // stabilzer end
        }
    ) // pagecreate end

}(window.jQuery, window, document)); // function end