javascript - 在 js 文件中为网络故障覆盖 "Error Loading Page"

标签 javascript android jquery-mobile

我有JQuery Mobile-1.0.js文件。

 // Load a page into the DOM.
    $.mobile.loadPage = function (url, options) {
        // This function uses deferred notifications to let callers
        // know when the page is done loading, or if an error has occurred.
        var deferred = $.Deferred(),

        // The default loadPage options with overrides specified by
        // the caller.
            settings = $.extend({}, $.mobile.loadPage.defaults, options),

        // The DOM element for the page after it has been loaded.
            page = null,

        // If the reloadPage option is true, and the page is already
        // in the DOM, dupCachedPage will be set to the page element
        // so that it can be removed after the new version of the
        // page is loaded off the network.
            dupCachedPage = null,

        // determine the current base url
            findBaseWithDefault = function () {
                var closestBase = ($.mobile.activePage && getClosestBaseUrl($.mobile.activePage));
                return closestBase || documentBase.hrefNoHash;
            },

        // The absolute version of the URL passed into the function. This
        // version of the URL may contain dialog/subpage params in it.
            absUrl = path.makeUrlAbsolute(url, findBaseWithDefault());


        // If the caller provided data, and we're using "get" request,
        // append the data to the URL.
        if (settings.data && settings.type === "get") {
            absUrl = path.addSearchParams(absUrl, settings.data);
            settings.data = undefined;
        }

        // If the caller is using a "post" request, reloadPage must be true
        if (settings.data && settings.type === "post") {
            settings.reloadPage = true;
        }

        // The absolute version of the URL minus any dialog/subpage params.
        // In otherwords the real URL of the page to be loaded.
        var fileUrl = path.getFilePath(absUrl),

        // The version of the Url actually stored in the data-url attribute of
        // the page. For embedded pages, it is just the id of the page. For pages
        // within the same domain as the document base, it is the site relative
        // path. For cross-domain pages (Phone Gap only) the entire absolute Url
        // used to load the page.
            dataUrl = path.convertUrlToDataUrl(absUrl);

        // Make sure we have a pageContainer to work with.
        settings.pageContainer = settings.pageContainer || $.mobile.pageContainer;

        // Check to see if the page already exists in the DOM.
        page = settings.pageContainer.children(":jqmData(url='" + dataUrl + "')");

        // If we failed to find the page, check to see if the url is a
        // reference to an embedded page. If so, it may have been dynamically
        // injected by a developer, in which case it would be lacking a data-url
        // attribute and in need of enhancement.
        if (page.length === 0 && dataUrl && !path.isPath(dataUrl)) {
            page = settings.pageContainer.children("#" + dataUrl)
                .attr("data-" + $.mobile.ns + "url", dataUrl);
        }

        // If we failed to find a page in the DOM, check the URL to see if it
        // refers to the first page in the application. If it isn't a reference
        // to the first page and refers to non-existent embedded page, error out.
        if (page.length === 0) {
            if ($.mobile.firstPage && path.isFirstPageUrl(fileUrl)) {
                // Check to make sure our cached-first-page is actually
                // in the DOM. Some user deployed apps are pruning the first
                // page from the DOM for various reasons, we check for this
                // case here because we don't want a first-page with an id
                // falling through to the non-existent embedded page error
                // case. If the first-page is not in the DOM, then we let
                // things fall through to the ajax loading code below so
                // that it gets reloaded.
                if ($.mobile.firstPage.parent().length) {
                    page = $($.mobile.firstPage);
                }
            } else if (path.isEmbeddedPage(fileUrl)) {
                deferred.reject(absUrl, options);
                return deferred.promise();
            }
        }

        // Reset base to the default document base.
        if (base) {
            base.reset();
        }

        // If the page we are interested in is already in the DOM,
        // and the caller did not indicate that we should force a
        // reload of the file, we are done. Otherwise, track the
        // existing page as a duplicated.
        if (page.length) {
            if (!settings.reloadPage) {
                enhancePage(page, settings.role);
                deferred.resolve(absUrl, options, page);
                return deferred.promise();
            }
            dupCachedPage = page;
        }

        var mpc = settings.pageContainer,
            pblEvent = new $.Event("pagebeforeload"),
            triggerData = { url: url, absUrl: absUrl, dataUrl: dataUrl, deferred: deferred, options: settings };

        // Let listeners know we're about to load a page.
        mpc.trigger(pblEvent, triggerData);

        // If the default behavior is prevented, stop here!
        if (pblEvent.isDefaultPrevented()) {
            return deferred.promise();
        }

        if (settings.showLoadMsg) {

            // This configurable timeout allows cached pages a brief delay to load without showing a message
            var loadMsgDelay = setTimeout(function () {
                $.mobile.showPageLoadingMsg();
            }, settings.loadMsgDelay),

            // Shared logic for clearing timeout and removing message.
                hideMsg = function () {

                    // Stop message show timer
                    clearTimeout(loadMsgDelay);

                    // Hide loading message
                    $.mobile.hidePageLoadingMsg();
                };
        }

        if (!($.mobile.allowCrossDomainPages || path.isSameDomain(documentUrl, absUrl))) {
            deferred.reject(absUrl, options);
        } else {
            // Load the new page.
            $.ajax({
                url: fileUrl,
                type: settings.type,
                data: settings.data,
                dataType: "html",
                success: function (html, textStatus, xhr) {
                    //pre-parse html to check for a data-url,
                    //use it as the new fileUrl, base path, etc
                    var all = $("<div></div>"),

                    //page title regexp
                        newPageTitle = html.match(/<title[^>]*>([^<]*)/) && RegExp.$1,

                    // TODO handle dialogs again
                        pageElemRegex = new RegExp("(<[^>]+\\bdata-" + $.mobile.ns + "role=[\"']?page[\"']?[^>]*>)"),
                        dataUrlRegex = new RegExp("\\bdata-" + $.mobile.ns + "url=[\"']?([^\"'>]*)[\"']?");


                    // data-url must be provided for the base tag so resource requests can be directed to the
                    // correct url. loading into a temprorary element makes these requests immediately
                    if (pageElemRegex.test(html)
                            && RegExp.$1
                            && dataUrlRegex.test(RegExp.$1)
                            && RegExp.$1) {
                        url = fileUrl = path.getFilePath(RegExp.$1);
                    }

                    if (base) {
                        base.set(fileUrl);
                    }

                    //workaround to allow scripts to execute when included in page divs
                    all.get(0).innerHTML = html;
                    page = all.find(":jqmData(role='page'), :jqmData(role='dialog')").first();

                    //if page elem couldn't be found, create one and insert the body element's contents
                    if (!page.length) {
                        page = $("<div data-" + $.mobile.ns + "role='page'>" + html.split(/<\/?body[^>]*>/gmi)[1] + "</div>");
                    }

                    if (newPageTitle && !page.jqmData("title")) {
                        if (~newPageTitle.indexOf("&")) {
                            newPageTitle = $("<div>" + newPageTitle + "</div>").text();
                        }
                        page.jqmData("title", newPageTitle);
                    }

                    //rewrite src and href attrs to use a base url
                    if (!$.support.dynamicBaseTag) {
                        var newPath = path.get(fileUrl);
                        page.find("[src], link[href], a[rel='external'], :jqmData(ajax='false'), a[target]").each(function () {
                            var thisAttr = $(this).is('[href]') ? 'href' :
                                    $(this).is('[src]') ? 'src' : 'action',
                                thisUrl = $(this).attr(thisAttr);

                            // XXX_jblas: We need to fix this so that it removes the document
                            //            base URL, and then prepends with the new page URL.
                            //if full path exists and is same, chop it - helps IE out
                            thisUrl = thisUrl.replace(location.protocol + '//' + location.host + location.pathname, '');

                            if (!/^(\w+:|#|\/)/.test(thisUrl)) {
                                $(this).attr(thisAttr, newPath + thisUrl);
                            }
                        });
                    }

                    //append to page and enhance
                    // TODO taging a page with external to make sure that embedded pages aren't removed
                    //      by the various page handling code is bad. Having page handling code in many
                    //      places is bad. Solutions post 1.0
                    page
                        .attr("data-" + $.mobile.ns + "url", path.convertUrlToDataUrl(fileUrl))
                        .attr("data-" + $.mobile.ns + "external-page", true)
                        .appendTo(settings.pageContainer);

                    // wait for page creation to leverage options defined on widget
                    page.one('pagecreate', $.mobile._bindPageRemove);

                    enhancePage(page, settings.role);

                    // Enhancing the page may result in new dialogs/sub pages being inserted
                    // into the DOM. If the original absUrl refers to a sub-page, that is the
                    // real page we are interested in.
                    if (absUrl.indexOf("&" + $.mobile.subPageUrlKey) > -1) {
                        page = settings.pageContainer.children(":jqmData(url='" + dataUrl + "')");
                    }

                    //bind pageHide to removePage after it's hidden, if the page options specify to do so

                    // Remove loading message.
                    if (settings.showLoadMsg) {
                        hideMsg();
                    }

                    // Add the page reference and xhr to our triggerData.
                    triggerData.xhr = xhr;
                    triggerData.textStatus = textStatus;
                    triggerData.page = page;

                    // Let listeners know the page loaded successfully.
                    settings.pageContainer.trigger("pageload", triggerData);

                    deferred.resolve(absUrl, options, page, dupCachedPage);
                },
                error: function (xhr, textStatus, errorThrown) {
                    //set base back to current path
                    if (base) {
                        base.set(path.get());
                    }

                    // Add error info to our triggerData.
                    triggerData.xhr = xhr;
                    triggerData.textStatus = textStatus;
                    triggerData.errorThrown = errorThrown;

                    var plfEvent = new $.Event("pageloadfailed");

                    // Let listeners know the page load failed.
                    settings.pageContainer.trigger(plfEvent, triggerData);

                    // If the default behavior is prevented, stop here!
                    // Note that it is the responsibility of the listener/handler
                    // that called preventDefault(), to resolve/reject the
                    // deferred object within the triggerData.
                    if (plfEvent.isDefaultPrevented()) {
                        return;
                    }

                    // Remove loading message.
                    if (settings.showLoadMsg) {

                        // Remove loading message.
                        hideMsg();

                        //show error message
                        $("<div class='ui-loader ui-overlay-shadow ui-body-e ui-corner-all'><h1>" + $.mobile.pageLoadErrorMessage + "</h1></div>")
                            .css({ "display": "block", "opacity": 0.96, "top": $window.scrollTop() + 100 })
                            .appendTo(settings.pageContainer)
                            .delay(800)
                            .fadeOut(400, function () {
                                $(this).remove();
                            });
                    }

                    deferred.reject(absUrl, options);
                }
            });
        }

        return deferred.promise();
    };

这是显示页面错误的错误消息 "Error Loading Page" 的代码。在这里,我想将网络连接失败的警报消息显示为 “请检查您的网络连接” 而不是下图。

Error Loading Page

注意:我不想更改页面加载错误消息。想停止获取页面错误消息,而不是我将启用我的网络错误条件,如 Show Network Error in android .如果用户在警告对话框中按下“确定”,我会将它们导航到 Reload.html。

请告诉我在哪里可以检查该条件以及我必须在哪里更改错误消息?

最佳答案

@shkschneider 和@codemonkey 都建议您需要在 mobileinit 上设置此选项

例子:

$(document).bind("mobileinit", function(){
    $.mobile.pageLoadErrorMessage = "Please check your net connection";
});

链接 jQM 1.0.1 文档:

这是一个例子:

现在,如果您有能力将 jQM 升级到 1.1.1,您可以尝试这样的操作:

//use theme swatch "b", a custom message, and no spinner
$.mobile.showPageLoadingMsg("b", "Please check your net connection", true);

// hide after delay
setTimeout( $.mobile.hidePageLoadingMsg, 1500 );

文档:

更新:

另一个想法是使用插件来实现你想要的东西,这样的东西行得通吗?

关于javascript - 在 js 文件中为网络故障覆盖 "Error Loading Page",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11305146/

相关文章:

javascript - 将鼠标悬停在选择器上时,Jquery 禁用双击

android - 如何以数学方式计算 Android 屏幕纵横比

javascript - 代码不适用于 Phonegap 应用程序

javascript - Jquery 旋转轨道与项目

javascript - 按值过滤对象数据

android - 无法解析的日期 : "2017-01-02T01:41:24Z" (at offset 10)

android - 如果执行异步任务时失去互联网连接,如何处理异常

javascript - JQM : popup not closing on timeout?

asp.net-mvc - 将 ASP.NET MVC 布局应用于 Jquery.Mobile 页面的最佳实践

javascript - bootstrap datepicker 显示选择的默认日期