Navigation Refactor - Content Container Widget #5427

johnbender opened this Issue Jan 8, 2013 · 13 comments


None yet
3 participants

johnbender commented Jan 8, 2013


With the history management and url handling abstracted into modules the next step is to build a container widget to handle virtually everything else that navigation does. That includes:

  1. loading content
  2. displaying content
  3. managing page caching
  4. base tag management (though this could be separated later)
  5. translation of nav state and url information to container state (content)
  6. content lifecycle events

The final output from this task should be something like:

  1. $.mobile.container (up for discussion)
  2. changePage alterations to account for a container. That is, making changePage a proxy to the widget.


The event targets will have to be container specific

The container widget will likely listen for navigation events and respond accordingly in the same way that the hashchange handling function in does now.

Dependency on jQuery, navigation and some change content function (eg, changePage )

It's possible that changePage and loadPage will get deprecated at this point in favor of the widget methods (they'll probably end up just forwarding arguments to the container widget itself)

This is in preparation for multiple containers in tablet layouts.

johnbender was assigned Jan 8, 2013


johnbender commented Apr 22, 2013

Updated notes on what should and should not be included in a content container widget from js/


  1. path
  2. base
  3. $.mobile.back
  4. removeActiveLinkClass
  5. releasePageTransitionLock - move to transitions?
  6. _maybeDegradeTransition - move to transitions?
  7. findBaseWithDefault
  8. $.fn.animationComplete - move to transitions?
  9. findClosestLink
  10. _registerInternalEvents


  1. handleHashChange
  2. navigate binding - unify _handleHashChange
  3. $.mobile.focusePage
  4. scroll position settings
  5. transitionPages - move to transitionContent?
  6. resetActivePageHeight
  7. enhancePage
  8. _bindPageRemove
  9. loadPage - move to loadContent, alias mobile property
  10. changePage - move to changeContent, alias mobile property


  • content management only
  • augment $.mobile.navigate to pass through args
  • switch link bindings in _registerInternalEvents to calling $.mobile.navigate instead of changePage

In and Out here refer to inclusion in the content container widget. That is, the goal is to manage the content of a container and dealing with other aspects of navigation may not necessarily make sense in the scope of that task. Obviously much of this may change in the face of the actual refactor.


frequent commented Apr 23, 2013


There once was a fetchlink functionality planned for JQM 1.past (here's a demo). I'm doing a lot of content-pulling and was thinking whether this should not be combined into the container widget.

Something like:

  • a page can have any number of <div data-role="container"></div> widgets.
  • like the <body> tag, all containers are viewports.
  • when doing a changePage, user can specify changePage option container="container_id" to override default <body> (normal changePage).
  • calling navigate vs changePage does sound better.
  • the loaded content will be appended to the container (... ui-container-page?)
  • changeHash option specifies whether this transition is tracked in urlHistory

JQM navigation more or less does this on a page level already (pulling a page, extracting content, appending, tracking in history), so containers would just be sort of a sub-navigation. This should allow pages to persist with only content changing, keep trackable history, plus transitions should work nicely, too.

I will try to see if I can hack an example together.



arschmitz commented Apr 23, 2013

@frequent fetch link is still on the roadmap but not until 1.6


johnbender commented Apr 25, 2013


A lot of what you outlined is what I have in mind for the content container.

  • This is the first pass at breaking up navigation but the ultimate purpose for having a content container is to allow multiple content containers on the same page for tablet UI applications
  • The default state is for jquery mobile applications to have a single container that defaults to the body. This is important because it informs how we'll replace changePage and loadPage as global methods.
  • This is where we differ, when this is finished the global changePage and loadPage will be deprecated, and will look something like:
$.mobile.changePage = function() { 
  $.mobile.defaultContainer.container( 'changeContent', opts ); 
  • This is the ideal. Calling $.mobile.navigate( 'some_url', opts) and letting the navigate binding of the content container widget "work it out". When we get to the point that the UI requires multiple containers we'll need to think through providing hooks for managing the individual urls and loading specific content based on them. We've had some very basic discussion around this but it's not clear how we can encode enough information in a url to designate the right content for multiple containers. One approach is to have a single "primary container" that retrieves the content at a url and uses that content to delegate content to other containers on the page. This is the point at which hooks would be provided to allow the client to determine how that content is delegated.

johnbender commented Apr 25, 2013

@frequent @arschmitz

One more note on link bindings.

I've talked with @gabrielschulhof about this but we can pretty easily setup $.mobile.navigate to pass arguments through when it triggers the navigate event so we can remove the $.mobile.changePage calls from our link bindings and make them an optional module.

Obviously that has implications for the "fetch links" in that they would just be links with a simple binding to trigger a navigate with some special options possibly.


johnbender commented Apr 25, 2013

Making a note here to thoroughly test scroll positioning across page and history navigation. We have one test in the suite so I'm concerned about cross browser issues like the timing in Firefox.


johnbender commented May 14, 2013


The work is proceeding quickly, you can view what has been moved to the content widget thus far here at the top of nav.

I have some ideas on allowing the content widget to stand on its own.

Generally this requires some form of configuration. So far we need to allow for callbacks (or some other method) for finding content that already exists in the DOM and enhancing new content that has just been loaded. An easy criteria for determining where we need this type of integration is JQM specific code. Eg, any method referencing our data attributes probably needs to be configurable or anything referencing a page.

On the other hand there's a lot of generally useful functionality built into nav. Eg, forcing a reload on a post, prefetching, caching, and events. We especially have to consider how each of these integration points works with the current navigation events.

As a side note the page* events have been deprecated in favor of content* events , eg pageloadfailed to contentloadfailed. And I'm working toward removing references to the notion of a page inside the content widget though there's still a lot to do in this regard (especially with the aforementioned customization).


johnbender commented May 14, 2013

Also, $elem.content( 'load', url, opts ); and $elem.content( 'change', to, opts ); are going to be sequential in the new widget. The recursive call in the current changePage implementation is problematic (eg, events). So $.mobile.changePage will wrap the two calls to load and change and ensure that backward compat is maintained.


johnbender commented May 23, 2013

Further thoughts on method purpose and changes.

The current state of things is that changePage makes a call to loadPage, does url manip, and content transitioning. In particular changePage embeds a recursive call in the deferred done callback from loadPage. I would like to make the changePage equivalent in the content widget (currently change) a wrapper that calls load and embeds a call to a separate method in the done callback. The method would most likely be transition. In addition I would like to make the change method as simple as possible as a proof of concept that users can call load and transition easily for themselves should the want to.


change - will remain the parent for loading and transitioning the content. It will take a string or an element and handle loading or transitioning it.

load - will of course load the remote content or use content currently in the page where it's provided.

transition - will handle taking an element (not a url) and moving that into focus in the container.

In this way, change becomes a convenience wrapper around load and transition which we can expose to users who want to have a sane model for doing either of those in isolation. That is, if they want to load the content themselves and let jqm do the transition or vice versa.

Obviously this will address the duplicate pagebeforechange issue: #3347


johnbender commented May 23, 2013

After this first pass is done it would be nice to turn the load, and transition methods into plain JS objects for organization's sake.


johnbender commented May 28, 2013

This is the soon to be event sequence for a call to element.content( 'change' ), without the page events triggered by the page widget:

Where each event name is prefixed with both a deprecated page or the new content (ie, two events will be fired) unless otherwise specified:

load || (loadfailed && changefailed)

assuming the page load succeeded

beforechange && beforetransition
show/hide && hide/show

Note that the second beforechange is deprecated in favor of beforetransition. The key is that the beforechange and change events bookend the load and transition events which follows directly from the fact that the change methods is a wrapper for the load and transition methods.


arschmitz commented Jul 18, 2013

The first round of work on this is now complete and merged into master. Please not this is currently still just internal reorganization and there is not a finalized public api yet.


arschmitz commented Sep 3, 2013

im going to close this since this is merged now

arschmitz closed this Sep 3, 2013

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment