For us to understand this situation we need to understand how jQuery Mobile works. It uses Ajax for page loading into the DOM.
 
First page is loaded normally. Its HEAD and BODY is loaded into the DOM. That content will stay there (unless page is refreshed) to await further content loading. When second page is loaded, only its BODY content is loaded into the DOM, and when I say its BODY content I mean DIV with an attribute data-role=”page” and its inner content.
 
This may not sound like something problematic, but you should think twice. What if we have several HTML pages and every and each page has something unique, let’s say different javascript intended to be used only during that page execution, not to mention additional CSS files. Everything found in a HEAD of those files are going to be discarded, and its javascript is not going to be executed.
 
Unfortunately, you are not going to find this described in their documentation. This is either thought to be a common knowledge or they just forgot to mention it.
 
There are several solutions to this problem; some are good and some are bad, everything should depend on a project architecture.
 
 

Note: If this tutorial was helpful, need further clarification, something is not working or do you have a request for another Ionic post? Furthermore, if you don't like something about this blog, if something is bugging you, don't like how I'm doing stuff here, again leave me a comment below. I'm here to help you, I expect the same from you. Feel free to comment below, subscribe to my blog, mail me to dragan.gaic@gmail.com, or follow and mention me on twitter (@gajotres). Thanks and have a nice day!

PS. If you want my help, if possible (even if it takes you some time to do that), create a working example I can play with. Use Plunker for AngularJS based questions or jsFiddle for jQuery/jQuery Mobile based questions.


 

Intro

 
This article is an response to my Stackoveflow answer that can be found here.
 

Solution 1

 
In your second page and every other page, move your SCRIPT tag into the BODY content, like this:
<body>
    <div data-role="page">
        <script>
            // Your javascript will go here
        </script>
        // And rest of your HTML content
    <div>
</body>
 
This is a quick solution but an ugly one.
 
Working example can be found in my other answer here: Pageshow not triggered after changepage
 
Another working example: Page loaded differently with jQuery-mobile transition
 

Solution 2

 
Move all of your javascript into the original first HTML. Collect everything and put it into a single js file, into a HEAD. Initialize it after jQuery Mobile has been loaded.
 
<head>
    <meta name="viewport" content="width=device-width; initial-scale=1.0; maximum-scale=1.0; minimum-scale=1.0; user-scalable=no; target-densityDpi=device-dpi"/>
    <link rel="stylesheet" href="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.css" />
    <script src="http://code.jquery.com/mobile/1.2.0/jquery.mobile-1.2.0.min.js"></script>    
    <script src="index.js"></script> // Put your code into a new file
</head>
 
At the end of this article, I will describe why this is a good solution.
 

Solution 3

 
Use rel=”external” in your buttons and every elements you are using to change page. Because of it, Ajax is not going to be used for page loading and your jQuery Mobile app will behave like a regular web application. Unfortunately, this is not that good solution. If Ajax is not used for page loading, you will loose a lot of functionalities that make jQuery Mobile such a great framework.
 
<a href="#second" class="ui-btn-right" rel="external">Next</a>
 
Official documentation, look for a chapter: Linking without Ajax.
 

Realistic solution

 
Realistic solution would use solution 2. But unlike solution 2, I would use that same index.js file and initialize it inside a HEAD of every possible other page.
 
Now, you may ask WHY is that?
 
jQuery Mobile is buggy, and sooner or later there’s going to be an error and your app will fail (including loaded DOM) if your js content is inside a single HTML file. DOM could be erased, and browser or you will refresh your current page. If that current HTML page don’t have javascript initialized inside its HEAD then that web app will not work until everything is restarted.
 
In the end, when creating a jQuery Mobile application spend some time thinking about a page architecture. If you need a help take a look at my other article where I am discussing secrets of a good jQuery Mobile architecture.
 

Who Am I?

Between working as a senior Java developer in one of the largest insurance companies in the world and traveling, in my free time, I work as a professional mobile development adviser. I'm also a major jQuery Mobile supporter back at StackOverflow and a forum moderator at the official Ionic Framework forum.

Blogs worth reading

If you're here looking for information related to the Ionic Framework, you will also like these blogs:






  • handoyo

    Hi,how are you?Thanks for the article,i got a problem with my script,the page won’t refresh as it should be.Sorry if what i ask is not related to your article,and I have followed your tutorial to put all the js script in head,but it doesn’t work.Unless i put the script like this :

    [index.html] http://pastebin.com/5XkrHFm2

    the javascript are like this :

    [login.js] http://pastebin.com/kZWZQaDL

    [dashboard.js] http://pastebin.com/7vfxBGVn

    And when i run the script and watch the firefox console,it gives me this :

    http://i575.photobucket.com/albums/ss197/yonghan79/ask.png

    The lowest part show GET http://localhost:81/testservice/js/dashboard.js?_=1384xxxx,i think that cause my page won’t refresh.Hope you would help me to point me what should i do.Thanks a lot and may God bless you. 🙂

  • Jesus

    great article i searched for hours and hours on how to do this and finally you made things clear and concise! Keep up the great work!

  • rob

    Perfect!
    Just what I was looking for – although I’d have wished there was a way to leave the ajax sliding affect with data-ajax=”false”…

  • Glen

    Great explanation. I was just wondering about your Realistic solution. You say to put the index.js in the head of every page, should that be in the body of every page?

    • My realistic solution was written when jQuery Mobile was in 1.2 version, current 1.4.2 is very stable so I would advise against placing index.js in the head of every page. You can still do it just to be on a safe side but that problem was fixed (or at least it didn’t manifest it self after jQuery Mobile 1.3 was released).

  • thbz

    Thanks for this very clear explanation!
    Solution 1 may not be the way the creators of HTML want us to write pages, but it seems much more logical and easier to maintain than solution 2, isn’t it?
    What is the purpose of a single-page model template structure if you still need to load all of your Javascript from the first page?

    • Unfortunately, this is how it is. I’m not happy with this solution, especially because nothing mentioned in my article can not be found in an official documentation.

      Single-page model is extremely useful in hybrid mobile applications. Basically, if we are to create a hybrid mobile application, the smartest thing to do would be to group all heavy duty pages (most commonly used pages)
      into one page that will always stay loaded into the memory. Unless configured manually, jQuery Mobile will never unload first page from the DOM, thus preventing possible performance problems during page loading/transition actions.

  • k, I did create several separate .html pages. Nine, and then to make them link to each other
    I can say <a href=”about.html” rel=”nofollow”>about</a> and it gets there.

    But if I say <a href=”about#history.html” rel=”nofollow”> it does NOT go there. This is cool, I can just put my about into the first main page and call it like this: #about#history.

    But if I create some separate .html pages like “terms.html”, I need a footer on that. The footer has a nav bar that leads to #history – so I would like still to be able to get to “index.html#about#history”. How do I do that?

    • If you are using classic AJAX page loading (default jQuery Mobile page loading) you only need to call #history.

  • prasad

    very nice…it helped me.

  • Alta

    Odd – you seem to have the answer to my dilemma – HOWEVER, I am finding content is messed up after typing the URL in the browser. Messed up = my panels that should be hidden are exposed one atop the other.

    I am using your solution # 1 because a lot of script is dynamic within the php program (enters vars obtained from php).

    This is driving me nuts. But I think you are close to the answer to my issue.

  • Rahul Unni

    Hello…I’ve a doubt,if i put my whole script for my mobile app put in single.js file and include it in tag of html
    how to maintain memory, There is lot of variables and function and callback functionalities over there so,how can i clear up unwanted variables when i navigate from one page two another.

    • You don’t need to worry about this unless we’re talking about a JS file that holds several MB of code. Then again you can always separate your app logic into several js files and dynamically load it depending on some requirements (using require.js).

      Though let me give you an advice. There’s no point in using jQuery Mobile any more. It’s slow, fat and dead. Find some time and learn how to use Ionic Framework or OnsenUI.

      • Rahul Unni

        Yes…i too…felt in sometime….its very slow. Ok anyway can u kindley give demonstration on how to dynamically load while navigating pages. in which page event i need to do so. thanks for your time.
        your articles reagrding jquery-mobile really helped me a lot . thank you. 🙂

        • Unfortunately, I don’t have time, I haven’t used jQuery Mobile in a while. Try googling it a bit. Though I don’t think you’ll find anything fresh, a lot of people have already abandoned jQuery Mobile.

          • Rahul Unni

            ok Thanks!!

  • R.O.

    Hello Dragan,
    Thanks for your good advises and illustrations all this while.
    I am new to mobile app development, however, i have a challenge to develop a banking app.
    This app will work just like online banking for customers. I would need your advise on what architecture to use.
    Also, i would like to point out that the internet in my country is not very robust as such.
    Thanks as i await your response.

  • Kaustubh

    Hello Gajotres,
    I am facing one issue. I have one site which has several html pages link on one page.
    I have script on the other page which i want to include.
    Now problem is that script is not loaded as I have used Jquery mobile, I used data-ajax=false that works fine for scripts but my css is still not loaded.
    And one more thing I have loader on the main page from where other pages are opened.
    I want to show loader.
    How can i do this?
    Thanks Hoping to get reply soon…:)

  • Bert Groothuis

    Thanks for ths article, i spent yesterday the whole day finding out why my jquery functionality didn’t work. I tried solution 2 from this article, but i still have to place the js script into the BODY part, otherwise it won’t work.

  • Ibrahim Samad

    Thanks.

    Please where is the best place to place jquerymobile js file, head or body? and under which circumstances will one be preferred over the other

  • Sukron Hidayatullah

    Thanks, I have added a script rel=”external” and was working on my web 😀

  • michael

    well its true my js file on 2nd page didnt work….but did u said all inside will be discarded..i have on HEAD why thats still loaded?