Initially I tried adding script section to my div data-role="content" section. Then I tried adding it to a section below and outside the div data-role="page" section. Then I tried adding to an external JS file.
I'm tempted to remove the Ajax page loading, as some people have suggested, but that doesn't feel right either. I have created a couple of simplistic html files (attached as text files) that illustrate how many times the initialisation is being called, and how unpredictable it seems, to me at least.
My JS and JQM are a not too advanced, so I would be grateful for simple explanations.
Thanks for your response. That's the first time I have come across the use of .on(). Thanks also for the simple explanation, much appreciated.
Once more question though, if that's OK? Each of my pages are separate files rather a single, multi-page document. Because I'm using ASP.NET with a masterpage framework (I know, not everyone's cup of tea), all of the common page outer structure is built for me, including the div data-role="page" and div data-role="content" sections, leaving me with place-holders to simply change the content. Because of this, I don't have access to the div data-role="page" element. My question is, can I surround the content in my data-role="content" section in a div, give this an id and use that instead as part of the initialisation?
Unfortunately I am not familiar with ASP.NET so I'm not sure how to answer that. A short answer would be no because pageinit is what it is, an event called when a page is initialized.
My questions in return - are you certain you have no access? Does it auto assign a page id? If you can't assign an ID can you assign a class to the page? You can use classes as well as ID's (actually recommended). Instead of using '#Pageid' you would use '.Pageclass'.
The only way I can think of getting around it is by having a global variable called something like isBound to make sure everything is only bound once. Can you provide an example? Perhaps the live site. I could help out better if I could see it.
I'll see if I can figure something out. In the mean time good luck!
Maybe you could back-up and explain what you are really trying to accomplish.
It's not conventional to write jQuery Mobile event code within pages. In most cases, it's best to have an external JS file that you reference from the <head> of every page.
In that file, you can initialize anything that only needs to be initialized once when the user enters your site. This might include initialization of variables and data structures, setting-up event callbacks, etc. You can use .on() or .delegate() to register callbacks for pages/elements that have not yet been loaded. (Please don't use .live() - it is obsolete and slow.)
For low-frequency events (page loads, etc.) it is sufficient to delegate to $(document) and let the events bubble up to the document. For high-frequency events (mouse position, for example) it's better to bind directly to the element or else delegate to something deeper inside the DOM, to limit how far the event has to bubble.
You can do this by first setting up a pageinit callback that will target the particular page(s) that contain the element(s) of interest, and then within that callback, use .find() to locate the element(s) and then set-up either delegations or direct binding to the element(s).
I think that you have again answered my question, thanks. Because the pageinit is only intended to operate on the div data-role="page" element, I'll have to change my architecture to suite. I appreciate your help and assistance.
I believe I see your issue. You should move the scripts to the <head> of your documents. This also means you should create an external JS file and include it on all of your pages. The JS in the <head> only gets loaded once, so if it's the same on every page it won't matter where you enter. I think this should solve your issues.
If you don't like having one file for all the JS you can create JS for each page (1, 2, and 3) but still include them all in the <head> of every page. This way there is some division between each page.
That makes sense I guess, thanks. One issue I may have, however, is that, while the test harness is simplistic, my actual pages have scripts make use of values that whose data is contextually bound to that page and data.
Allow me to explain in a little more detail. If the user were to select some values on page 1 and submit these to page 2, page 2 would dynamically make use of those values to render it's contents, such as drop-down select lists. This means that the JS (JSON) used to build the drop-down lists can only be determined at run-time and only by the page in which the user finds himself/herself.
I tend to have a JS method that is injected into the page and contains server settings, something like this:
I don't think this should be an issue at all. There are page events in JQuery mobile you can make use of. For example, as you said every time the users enters "Page 2", it will load the dynamic content. Here you can use the pagebeforeshow event to initialize data before the user sees the page.
I think if you look through the events documentation it will be a bit more clear to you. I hope this answers your questions. If I misunderstood your problem let me know and I'll take another look.
Thanks again for both your input. I have now fully solved my problem (touch wood), and I can give the following feedback as to what my causes and subsequent remedies were:
Initialisation Scripts Cannot Be Embedded In The Page It would seem that if you have any initialisation scripts within your page, as I had, they are called in an unpredictable way as the page is loaded and unloaded. That is to say anything that starts something like $(document).on("pageinit"...
. Most scripts, and especially the initialisation scripts, should be lumped together for the entire site and loaded as part of the <head> of the very first page, or each and every page, JQM will then cache them.
That is not to say that scripts cannot be embedded within the page, they can. However, it is safer to declare initialisation scripts and event scripts (such as $(selector).on("change"... ) separate to the page in a separate script declared in the <head> section. Remember though, that these must be declared within the first page or each page regardless of which page it is intended to be run in.
Html IDs While Unique to a Page May Still Not Be Unique Traditionally, Html element IDs should be unique to the page within which they appear. In other words, you really shouldn't have elements with the same IDs on the same page, this is what classes are for. However, since JQM may load several pages at a time, it is entirely possible that IDs unique to a page may still clash with IDs of the same name used on other pages. For instance, suppose you have a <select> declare on page-a and page-b that shows more or less the same data and you give it an ID of AvailableDates, then as JQM loads both page-a and page-b simultaneously, accessing the <select> on page-b may not be as straight forward as it seems. It appears that JQM doesn't know whether you want the <select> from page-a or page-b and may get confused.
Use jQuery Context in With Selectors To get around the issue described in point 2) above, you could simply make all of your IDs globally unique. This may be OK for you, but for larger, more complex sites, this may become tedious and harder to maintain if not thought through. jQuery offers an alternative in the form of a context when using selectors. If you have given your JQM page element a unique ID or a unique class name, this can be used in the jQuery select statement as the context.
So, if your JQM page has an ID of JqmPage1, then the selector mentioned in point 2) $("#AvailableDates") can be modified to $("#AvailableDates", "#JqmPage1"). By providing the context, you remove any ambiguity and JQM now understands exactly which element you have requested.
I think that this should be put forward as a candidate for "Best Practice" when using JQM. For more information on the jQuery context, see http://api.jquery.com/jQuery/.
Thanks again for all of your help. I have learned a lot and it has helped me push my project forward.
Leave a comment on kainevarley's reply
Change topic type
Link this topic
Provide the permalink of a topic that is related to this topic