Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Application Displays Unstyled Html Before It Renders Jquery Mobile

I am dynamically adding markup to my application an example code below..

$(document).bind("pagechange", function (event, ui) {
  var header = '<h3>' + appNames[i] + '</h3>';

        var ulHeader = '<ul data-role="listview" id="myAppsGridTable" data-inset="true">';

..
   $('.myBodyContent', ui.toPage).append(collapse + header + ulHeader + entire_list + '</ul>' + '</div>');
    $('#NicksPage').trigger('create');

});

I have a reference to this page in my Default.aspx page and a reference to jquery mobile in the master page. When you navigate to Default the user sees raw unstlyed html added to the page then a flicker and the jquery mobile styles come in. Is there anyway I can get rid of displaying the unstlyed html to the user sees before the jquery mobile styles are added?

Here is a copy of my master page:

<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="UserMobile.master.cs" Inherits="User.Mobile.UserMobile" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head id="Head1" runat="server">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link href="Css/jquery.mobile.custom.structure.min.css" rel="stylesheet" type="text/css" />
    <link href="Css/jquery.mobile.custom.theme.min.css" rel="stylesheet" type="text/css" />

    <asp:ContentPlaceHolder ID="HeadContent" runat="server">
    </asp:ContentPlaceHolder>
</head>

<body>

<div data-role="page" data-theme="b" id="NicksPage">

    <div data-role="header" data-position="fixed" data-theme="b">

         <asp:ContentPlaceHolder ID="TopHeaderContent" runat="server"></asp:ContentPlaceHolder>


    </div><!-- /header -->

    <div data-role="content" class="myBodyContent"> 

 <asp:ContentPlaceHolder ID="MainContent" runat="server"></asp:ContentPlaceHolder>

    </div><!-- /content -->

    <div data-role="footer" data-position="fixed" data-theme="b">
    <asp:ContentPlaceHolder ID="FooterContent" runat="server"></asp:ContentPlaceHolder>


    <input type="hidden" id="collapse_value" value="false" />
    </div><!-- /footer -->

</div><!-- /page -->

   //Combined jquery 1.8 and jquery mobile files in one
   <script src="Js/JQ_JQM_combined.js" type="text/javascript"></script>

    //Makes ajax calls to get data
    <script src="Js/UserMobile.js" type="text/javascript"></script>

    <script type="text/javascript">
        $(document).ready(function () {

            // disable page transitions
            $.mobile.ajaxEnabled = false;
            $.mobile.defaultPageTransition = 'none';
        });

    </script>
     <asp:ContentPlaceHolder ID="ScriptContent" runat="server"></asp:ContentPlaceHolder>

</body>

</html>

Even the Home page has the flicker problem, where it renders unstyled and then after a period of time properly styled to jquery mobile..

<%@ Page Title="" Language="C#" MasterPageFile="~/Mobile/UserMobile.Master" AutoEventWireup="true" CodeBehind="Home.aspx.cs" Inherits="User.Mobile.Home" %>
<asp:Content ID="Content1" ContentPlaceHolderID="HeadContent" runat="server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="TopHeaderContent" runat="server">
    <h1>
        Applications</h1>
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="MainContent" runat="server">
<div data-role="controlgroup">
<a href="MyStuff.aspx?name=nick&id=1234" data-role="button">My Stuff</a>
<a href="Employees.aspx?name=nick&id=1234" data-role="button">Employees</a>
<a href="list.aspx?name=nick&id=1234" data-role="button">List</a>

</div>


</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="FooterContent" runat="server">
    <div class="lines">
        <div class="footerCopyrightContainer">
            <div class="footerCopyright">
                &copy;2012 NICK ALL RIGHTS RESERVED.</div>
        </div>
    </div>
</asp:Content>

I changed my code to reflect your fiddle example but am still getting the flicker. But the "period of time where the flicker the unstyled to styled is shorter the user still sees the unstyled page in the mobile browser. Can you take a look fo how I got it setup am I missing something?

$(document).bind("pagecreate", function (event, ui) {

    //gets params needed from querystring
    arrQrStr = getQueryStringParams();
    name = arrQrStr["name"];
    id = arrQrStr["id"];

});


$(document).delegate('div[data-role=page]', 'pagebeforeshow', function (e, data) {

    var employees = null;

    //returns string of html needed
    employees = getData(name, id);

    $('.myBodyContent', this).html(employees);

    $(this).trigger('create');

});

getData ajax call..

 $.ajax({
        type: "POST",
        url: "MobileService.svc/REST/GetData",
        contentType: "application/json; charset=utf-8",
        data: JSON.stringify({ id: id}),
        dataType: "json",
        async: false,
        success: function (msg) {

The problem has comes from this:

  <script type="text/javascript">
      $(document).ready(function () {


          // disable page transitions
          $.mobile.ajaxEnabled = false;
          $.mobile.defaultPageTransition = 'none';



      });


    </script>

If I take this out of the master page the flicker goes away, it navigates a page fine but the data will not show. Taking this script out breaks the ajax calls and jquery mobile events dont engage (I am not sure why)

like image 271
Nick LaMarca Avatar asked Nov 04 '22 16:11

Nick LaMarca


1 Answers

It sounds like you misunderstood how the ajax enabled settings works.

By default this setting is enabled and when you link to another page JQM pulls in the the first JQM page that it finds (data-role="page") on the linked page (so you can't link to a multipage document) and enhances it (initializing all the JQM widgets) and then attaches it to the DOM of the current page. When JQM does this it only pulls in the JQM page and nothing else on that page (so any scripts and styling on the second page won't have any effect). The way to deal with this is to have all your scripts in the current main page. One thing you will need to look out for if you do this is that you might end up with multiple pages with the same id (actually with your current setup you definitely will have duplicate ids) so you might want to select them by class instead.

With ajax enabled set to false on the other hand it behaves like a regular link in which case the full page is loaded and if your JQM scripts are on the bottom then then until it's loaded it won't be able to enhance the DOM which is why you are seeing that flicker.

As a side point page transistions are only available ifajax enabledis set totrue`.

To sum up, unless you have a reason not to you probablly should go with ajax enabled set to true, and inlcude the relevant scripts on your main page. If you need to go with ajax enabled set to false then try placing your jQuery scripts in the header so that they load before the rest of the DOM.

Alternaticely what you can do is hide the container element where you will be appending you html and then once your done display it, for example

CSS

.displayNone { display: none; }

HTML

 <div data-role="content" class="myBodyContent displayNone"> 
      <asp:ContentPlaceHolder ID="MainContent" runat="server"></asp:ContentPlaceHolder>
    </div>

JS

 $('.myBodyContent', this).html(employees);
    $(this).trigger('create');
    $('.myBodyContent', this).reomveClass('displayNone');
like image 136
Jack Avatar answered Nov 11 '22 15:11

Jack