2012-07-03 91 views
4

我有JQuery Mobile-1.0.js文件。覆蓋js文件中網絡故障的「Error Loading Page Error」

// 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"的代碼。在這裏,我想顯示網絡連接失敗的警報消息爲"Please check your net connection",而不是下面的圖像。

Error Loading Page

注:我不想改變pageloaderrormessage。想要停止獲取頁面錯誤消息,而不是我將啓用我的網絡錯誤條件,如Show Network Error in android。如果用戶在提示對話框中按下「確定」,我將導航到Reload.html。

請告訴我在哪裏可以檢查這種情況,以及我在哪裏必須更改錯誤消息?

回答

4

由於兩個@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); 

文檔:

UPDATE:

另一個想法是使用一個插件來實現的東西像你想,難道是這樣的工作?

+0

感謝您的回答。您已提供解決方案來更改錯誤消息。但我想顯示警告對話框(我在問題中提到過),爲什麼因爲如果用戶點擊確定,那麼我將導航他們重新加載頁面。 – Ponmalar

+0

@Ponmalar你已經給出了我認爲與對話語言相關的jQM錯誤消息彈出窗口的例子。您是否正在尋找與對話的用戶互動?你應該只能使用對話框()或者確認()。你能再解釋一下嗎? –

+0

我已經處理了網絡錯誤消息,如http://stackoverflow.com/questions/11261193/show-network-error-in-android。請看看這個。但是這個警告對話框除了使用dialog()本身外,還顯示錯誤消息「Error loading page」 – Ponmalar

3

設置pageLoadErrorMessage這裏描述http://jquerymobile.com/demos/1.1.1/docs/api/globalconfig.html

編輯

如果你想處理一個自定義的方式行爲,設置loadingMessage爲false。這可以防止顯示加載消息。您可以綁定到pageloadfailed(此處描述的http://jquerymobile.com/demos/1.1.1/docs/api/events.html),並添加您的自定義處理邏輯到事件處理程序中。

+0

謝謝您的回答。您已提供解決方案來更改錯誤消息。但我想顯示警告對話框(問題中提到),爲什麼因爲如果用戶點擊確定,然後我將導航他們重新加載頁面 – Ponmalar

+0

編輯顯示自定義處理頁面加載錯誤的選項 – codemonkey

3

只需使用:

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

http://jquerymobile.com/test/docs/api/globalconfig.html

+0

感謝您的回答。你已經給出瞭解決方案來隱藏錯誤消息。但我想顯示警告對話框的錯誤消息「請檢查您的網絡連接」,爲什麼,因爲如果用戶點擊確定,那麼我將導航他們重新加載頁面 – Ponmalar

+0

我的壞。我編輯了我的答案。 – shkschneider