Permalink
Browse files

add note about load order ambiguity in ajax loaded page scripts fixes #…

  • Loading branch information...
1 parent d38b3ed commit e7f21575bec55a5fe0d409063b3005b6a3086788 @johnbender johnbender committed Apr 11, 2012
Showing with 43 additions and 43 deletions.
  1. +43 −43 docs/pages/page-scripting.html
View
86 docs/pages/page-scripting.html
@@ -1,18 +1,18 @@
-<!DOCTYPE html>
+<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
- <meta name="viewport" content="width=device-width, initial-scale=1">
- <title>jQuery Mobile Docs - Scripting pages</title>
- <link rel="stylesheet" href="../../css/themes/default/jquery.mobile.css" />
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+ <title>jQuery Mobile Docs - Scripting pages</title>
+ <link rel="stylesheet" href="../../css/themes/default/jquery.mobile.css" />
<link rel="stylesheet" href="../_assets/css/jqm-docs.css"/>
<script src="../../js/jquery.js"></script>
<script src="../../docs/_assets/js/jqm-docs.js"></script>
<script src="../../js/"></script>
-</head>
-<body>
+</head>
+<body>
<div data-role="page" class="type-interior">
@@ -23,24 +23,24 @@
</div><!-- /header -->
<div data-role="content">
- <div class="content-primary">
- <h2>Scripting pages in jQuery Mobile</h2>
- <p>Since jQuery Mobile uses an Ajax-powered navigation system, there are a few helpful things to know when writing scripts that manipulate your content. You can explore the mobile API in more detail by reading up on <a href="../api/globalconfig.html">global configuration options</a>, <a href="../api/events.html">events</a>, and <a href="../api/methods.html">methods</a> or dig into the technical details of the <a href="page-navmodel.html">Ajax navigation model</a>.</p>
-
- <h2>Scripts &amp; styles in the head</h2>
-
- <p>When the user clicks a link in a jQuery Mobile-driven site, the default behavior of the navigation system is to use that link's <code>href</code> to formulate an Ajax request (instead of allowing the browser's default link behavior of requesting that <code>href</code> with full page load). When that Ajax request goes out, the framework will receive its entire text content, but it will only inject the <em>contents of the response's <code>body</code> element (or more specifically the <code>data-role="page"</code> element, if it's provided)</em>, meaning nothing in the <code>head</code> of the page will be used (with the exception of the page title, which is fetched specifically).</p>
-
+ <div class="content-primary">
+ <h2>Scripting pages in jQuery Mobile</h2>
+ <p>Since jQuery Mobile uses an Ajax-powered navigation system, there are a few helpful things to know when writing scripts that manipulate your content. You can explore the mobile API in more detail by reading up on <a href="../api/globalconfig.html">global configuration options</a>, <a href="../api/events.html">events</a>, and <a href="../api/methods.html">methods</a> or dig into the technical details of the <a href="page-navmodel.html">Ajax navigation model</a>.</p>
+
+ <h2>Scripts &amp; styles in the head</h2>
+
+ <p>When the user clicks a link in a jQuery Mobile-driven site, the default behavior of the navigation system is to use that link's <code>href</code> to formulate an Ajax request (instead of allowing the browser's default link behavior of requesting that <code>href</code> with full page load). When that Ajax request goes out, the framework will receive its entire text content, but it will only inject the <em>contents of the response's <code>body</code> element (or more specifically the <code>data-role="page"</code> element, if it's provided)</em>, meaning nothing in the <code>head</code> of the page will be used (with the exception of the page title, which is fetched specifically). Please note that script's loaded dynamically in this fashion do not guarantee a load order in the same way they would if the page was loaded via a normal http request.</p>
+
<p> This means that any scripts and styles referenced the <code>head</code> of a page won't have any effect <em>when a page is loaded via Ajax</em>, but they <strong>will execute if the page is requested normally via HTTP</strong>. When scripting jQuery Mobile sites, both scenarios need to be considered. The reason that the <code>head</code> of a page is ignored when requested via Ajax is that the potential of re-executing the same JavaScript is very high (it's common to reference the same scripts in every page of a site). Due to the complexity of attempting to work around that issue, we leave the task of executing page-specific scripts to the developer, and assume <code>head</code> scripts are only expected to execute once per browsing session.</p>
-
+
<p>The simplest approach when building a jQuery Mobile site is to reference the same set of stylesheets and scripts in the head of every page. If you need to load in specific scripts or styles for a particular page, we recommend binding logic to the <code>pageInit</code> event (details below) to run necessary code when a specific page is created (which can be determined by its <code>id</code> attribute, or a number of other ways). Following this approach will ensure that the code executes if the page is loaded directly or is pulled in and shown via Ajax.</p>
<p>Another approach for page-specific scripting would be to include scripts at the end of the <code>body</code> element when no <code>data-role=page</code> element is defined, or inside the first <code>data-role=page</code> element. If you include your custom scripting this way, be aware that these scripts will execute when that page is loaded via Ajax or regular HTTP, so if these scripts are the same on every page, you'll likely run into problems. If you're including scripts this way, we'd recommend enclosing your page content in a <code>data-role="page"</code> element, and placing scripts that are referenced on every page outside of that element. Scripts that are unique to that page can be placed in that element, to ensure that they execute when the page is fetched via Ajax.</p>
<h2>pageinit = DOM ready</h2>
<p>One of the first things people learn in jQuery is to use the <code>$(document).ready()</code> function for executing DOM-specific code as soon as the DOM is ready (which often occurs long before the <code>onload</code> event). However, in jQuery Mobile site and apps, pages are requested and injected into the same DOM as the user navigates, so the DOM ready event is not as useful, as it only executes for the first page. To execute code whenever a new page is loaded and created in jQuery Mobile, you can bind to the <a href="../api/events.html"><code>pageinit</code></a> event. </p>
-
+
<p>The <code>pageinit</code> event is triggered on a page when it is initialized, right after initialization occurs. Most of jQuery Mobile's official widgets auto-initialize themselves based on this event, and you can set up your code to do the same.</p>
<pre><code>
$( document ).delegate("#aboutPage", "pageinit", function() {
@@ -49,7 +49,7 @@
</code></pre>
<p>If you'd like to manipulate a page's contents <em>before</em> the pageinit event fires and widgets are auto-initialized, you can instead bind to the <code>pagebeforecreate</code> event:</p>
-
+
<pre><code>
$( document ).delegate("#aboutPage", "pagebeforecreate", function() {
alert('A page with an ID of "aboutPage" is about to be created by jQuery Mobile!');
@@ -61,52 +61,52 @@ <h4 style="margin:.5em 0">Important note: <code>pageCreate()</code> vs <code>pag
In short, if you were previously using <code>pagecreate</code> to manipulate the enhanced markup before the page was shown, it's very likely you'll want to migrate to 'pageinit'.
</p>
-
- <h2>Changing pages</h2>
+
+ <h2>Changing pages</h2>
<p>If you want to change the current active page with JavaScript, you can use the <a href="../api/methods.html"><code>changePage</code></a> method. There are a lot of methods and properties that you can set when changing pages, but here are two simple examples:</p>
<pre><code>
-<strong>//transition to the "about us" page with a slideup transition</strong>
-$.mobile.changePage( "about/us.html", { transition: "slideup"} );
+<strong>//transition to the "about us" page with a slideup transition</strong>
+$.mobile.changePage( "about/us.html", { transition: "slideup"} );
-<strong>//transition to the "search results" page, using data from a form with an ID of "search"" </strong>
+<strong>//transition to the "search results" page, using data from a form with an ID of "search"" </strong>
$.mobile.changePage( "searchresults.php", {
- type: "post",
+ type: "post",
data: $("form#search").serialize()
-});
+});
</code></pre>
- <h2>Loading pages</h2>
+ <h2>Loading pages</h2>
<p>To load an external page, enhance its content, and insert it into the DOM, use the <a href="../api/methods.html"><code>loadPage</code> method</a>. There are a lot of methods and properties that you can set when loading pages, but here is a simple example:</p>
<pre><code>
-//load the "about us" page into the DOM
-$.mobile.loadPage( "about/us.html" );
+//load the "about us" page into the DOM
+$.mobile.loadPage( "about/us.html" );
</code></pre>
- <h2>Enhancing new markup</h2>
- <p>The page plugin dispatches a <code>pageInit</code> event, which most widgets use to auto-initialize themselves. As long as a widget plugin script is referenced, it will automatically enhance any instances of the widgets it finds on the page.</p>
- <p>However, if you generate new markup client-side or load in content via Ajax and inject it into a page, you can trigger the <code>create</code> event to handle the auto-initialization for all the plugins contained within the new markup. This can be triggered on any element (even the page <code>div</code> itself), saving you the task of manually initializing each plugin (listview button, select, etc.).</p>
- <p>For example, if a block of HTML markup (say a login form) was loaded in through Ajax, trigger the <code>create</code> event to automatically transform all the widgets it contains (<a href="http://jquerymobile.com/test/docs/forms/textinputs/index.html">inputs</a> and <a href="http://jquerymobile.com/test/docs/buttons/index.html">buttons</a> in this case) into the enhanced versions. The code for this scenario would be:</p>
+ <h2>Enhancing new markup</h2>
+ <p>The page plugin dispatches a <code>pageInit</code> event, which most widgets use to auto-initialize themselves. As long as a widget plugin script is referenced, it will automatically enhance any instances of the widgets it finds on the page.</p>
+ <p>However, if you generate new markup client-side or load in content via Ajax and inject it into a page, you can trigger the <code>create</code> event to handle the auto-initialization for all the plugins contained within the new markup. This can be triggered on any element (even the page <code>div</code> itself), saving you the task of manually initializing each plugin (listview button, select, etc.).</p>
+ <p>For example, if a block of HTML markup (say a login form) was loaded in through Ajax, trigger the <code>create</code> event to automatically transform all the widgets it contains (<a href="http://jquerymobile.com/test/docs/forms/textinputs/index.html">inputs</a> and <a href="http://jquerymobile.com/test/docs/buttons/index.html">buttons</a> in this case) into the enhanced versions. The code for this scenario would be:</p>
<pre style="margin: 25px 0;"><code style="font-size: 12px;">$( ...new markup that contains widgets... ).appendTo( ".ui-page" ).trigger( "create" );
-</code></pre>
+</code></pre>
- <h2>Create vs. refresh: An important distinction</h2>
- <p>Note that there is an important difference between the <code>create</code> event and <code>refresh</code> method that some widgets have. The <code>create</code> event is suited for enhancing <em>raw markup</em> that contains one or more widgets. The <code>refresh</code> method should be used on existing (already enhanced) widgets that have been manipulated programmatically and need the UI be updated to match.</p>
+ <h2>Create vs. refresh: An important distinction</h2>
+ <p>Note that there is an important difference between the <code>create</code> event and <code>refresh</code> method that some widgets have. The <code>create</code> event is suited for enhancing <em>raw markup</em> that contains one or more widgets. The <code>refresh</code> method should be used on existing (already enhanced) widgets that have been manipulated programmatically and need the UI be updated to match.</p>
<p>For example, if you had a page where you dynamically appended a new unordered list with <code>data-role=listview</code> attribute after page creation, triggering <code>create</code> on a parent element of that list would transform it into a <a href="http://jquerymobile.com/test/docs/lists/index.html">listview</a> styled widget. If more list items were then programmatically added, calling the listview&#8217;s <code>refresh</code> method would update just those new list items to the enhanced state and leave the existing list items untouched.</p>
- <h2>Scrolling to a position within a page</h2>
+ <h2>Scrolling to a position within a page</h2>
<p>Since we use the URL hash to preserve Back button behavior, using page anchors to jump down to a position on the page isn't supported by using the traditional anchor link (#foo). Use the <a href="../api/methods.html"><code>silentScroll</code></a> method to scroll to a particular Y position without triggering scroll event listeners. You can pass in a <code>yPos</code> arguments to scroll to that Y location. For example:</p>
<pre><code>
-//scroll to Y 300px
-$.mobile.silentScroll(300);
-</code></pre>
-
- <h2>Binding to mouse and touch events</h2>
+//scroll to Y 300px
+$.mobile.silentScroll(300);
+</code></pre>
+
+ <h2>Binding to mouse and touch events</h2>
<p>One inportant consideration in mobile is handling mouse and touch events. These events differ significantly across mobile platforms, but the common denominator is that click events will work everywhere, but usually after a significant delay of 500-700ms. This delay is necessary for the browser to wait for double tap, scroll and extended hold tap events to potentially occur. To avoid this delay, it's possible to bind to touch events (ex. touchstart) but the issue with this approach is that some mobile platforms (WP7, Blackberry) don't support touch. To compound this issue, some platforms will emit <em>both</em> touch and mouse events so if you bind to both types, duplicate events will be fired for a single interaction.</p>
<p>Our solution is to create a set of <a href="../api/events.html">virtual events</a> that normalize mouse and touch events. This allows the developer to register listeners for the basic mouse events, such as mousedown, mousemove, mouseup, and click, and the plugin will take care of registering the correct listeners behind the scenes to invoke the listener at the fastest possible time for that device. This still retains the order of event firing in the traditional mouse environment, should multiple handlers be registered on the same element for different events. The virtual mouse system exposes the following virtual events to jQuery bind methods: <code>vmouseover</code>, <code>vmousedown</code>, <code>vmousemove</code>, <code>vmouseup</code>, <code>vclick</code>, and <code>vmousecancel</code></p>
-
+
<h2>Passing parameters between pages</h2>
<p>jQuery Mobile does not support query parameter passing to internal/embedded pages. For example, if the framework sees a link to "#somePage?someId=1" it interpret that as "#somePage" and navigate to the internal page div with an ID of <code>somePage</code> and apply a data-url of <code>#somePage?someId=1</code> to that page container. Subsequent calls to other params such as "#somePage?someId=2" will find the same div because jQuery Mobile refers to the data-url on the div which is only set once and will remain at <code>#somePage?someId=1</code>.</p>
@@ -115,7 +115,7 @@ <h4 style="margin:.5em 0">Important note: <code>pageCreate()</code> vs <code>pag
- </div><!--/content-primary -->
+ </div><!--/content-primary -->
<div class="content-secondary">
@@ -142,7 +142,7 @@ <h4 style="margin:.5em 0">Important note: <code>pageCreate()</code> vs <code>pag
<li><a href="pages-themes.html">Theming pages</a></li>
</ul>
</div>
- </div>
+ </div>
</div><!-- /content -->

0 comments on commit e7f2157

Please sign in to comment.