Skip to content
This repository has been archived by the owner on Oct 8, 2021. It is now read-only.

Page Transition Plugins

jblas edited this page Jun 17, 2011 · 18 revisions

Overview

After Alpha 4.1, jQuery Mobile developers can create their own custom page transitions and override existing ones. This document describes how developers can create custom transitions with pure CSS3, or in combination with JavaScript.

Pure CSS3 Based Transitions

Up until jQuery Mobile Alpha 4.1, the only way to add a custom page transition was to implement it with CSS3 transitions or animation keyframes.

To create a custom CSS transition, you select a class name that corresponds to the name of your transition, for example "slide", and then define your "in" and "out" CSS rules to take advantage of transitions or animation keyframes:

.slide.in {
    -webkit-transform: translateX(0);
    -webkit-animation-name: slideinfromright;
}

.slide.out {
    -webkit-transform: translateX(-100%);
    -webkit-animation-name: slideouttoleft;
}

@-webkit-keyframes slideinfromright {
    from { -webkit-transform: translateX(100%); }
    to { -webkit-transform: translateX(0); }
}
@-webkit-keyframes slideouttoleft {
    from { -webkit-transform: translateX(0); }
    to { -webkit-transform: translateX(-100%); }
}

During a CSS-based page transition, jQuery Mobile will place the class name of the transition on both the "from" and "to" pages involved in the transition. It then places an "out" class on the "from" page, and "in" class on the "to" page. The presence of these classes on the "from" and "to" page elements then triggers the animation CSS rules defined above.

If your transition supports a reverse direction, you need to create CSS rules that use the "reverse" class in addition to the transition class name and the "in" and "out" classes:

.slide.in.reverse {
    -webkit-transform: translateX(0);
    -webkit-animation-name: slideinfromleft;
}

.slide.out.reverse {
    -webkit-transform: translateX(100%);
    -webkit-animation-name: slideouttoright;
}

@-webkit-keyframes slideinfromleft {
    from { -webkit-transform: translateX(-100%); }
    to { -webkit-transform: translateX(0); }
}

@-webkit-keyframes slideouttoright {
    from { -webkit-transform: translateX(0); }
    to { -webkit-transform: translateX(100%); }
}

After the CSS rules are in place, you simply specify the name of your transition within the @data-transition attribute of a navigation link:

<a href="#page2" data-transition="slide">Page 2</a>

When the user clicks on the navigation link, jQuery Mobile will invoke your transition when it navigates to the page mentioned within the link.

In case you were wondering why none of the CSS rules above specified any easing or duration, it's because the CSS for jQuery Mobile defines the default easing and duration in the following rules:

.in, .out {
    -webkit-animation-timing-function: ease-in-out;
    -webkit-animation-duration: 350ms;
}

If you need to specify a different easing or duration, simply add the appropriate CSS3 property to your custom page transition rules.

JavaScript-Based Transitions

When a user clicks on a link within a page, jQuery Mobile checks if the link specifies a @data-transition attribute. The value of this attribute is the name of the transition to use when displaying the page referred to by the link. If there is no @data-transition attribute, the transition name specified by the configuration option $.mobile.defaultPageTransition is used for pages, and $.mobile.defaultDialogTransition is used for dialogs.

After the new page is loaded, the $.mobile.transitionHandlers dictionary is used to see if any transition handler function is registered for the given transition name. If a handler is found, that handler is invoked to start and manage the transition. If no handler is found the handler specified by the configuration option $.mobile.defaultTransitionHandler is invoked.

By default, the $.mobile.transitionHandlers dictionary is only populated with a single handler entry called "none". This handler simply removes the "ui-page-active" class from the page we are transitioning "from", and places it on the page we are transitioning "to". The transition is instantaneous; no animation, no fanfare.

The $.defaultTransitionHandler points to a handler function that assumes the name is a CSS class name, and implements the "Pure CSS3 Based Transitions" section above.

Both the "none" and "css3" transition handlers are available off of the $.mobile namespace:

$.mobile.noneTransitionHandler
$.mobile.css3TransitionHandler

Transition Handlers

A transition handler is a function with the following call signature:

function myTransitionHandler(name, reverse, $to, $from)
{
    var deferred = new $.Deferred();

    // Perform any actions or set-up necessary to kick-off
    // your transition here. The only requirement is that
    // whenever the transition completes, your code calls
    // deferred.resolve(name, reverse, $to, $from).

    // Return a promise.
    return deferred.promise();
}

Your handler must create a Deferred object and return a promise to the caller. The promise is used to communicate to the caller when your transition is actually complete. It is up to you to call deferred.resolve() at the correct time. If you are new to Deferred objects, you can find documentation here.

Registering and Invoking Your Transition Handler

Once you have created a transition handler function, you need to tell jQuery Mobile about it. To do this, simply add your handler to the $.mobile.transitionHandlers dictionary. Remember, the key used should be the name of your transition. This name is also the same name that will be used within the @data-transition attribute of any navigation links.

// Define your transition handler:

function myTransitionHandler(name, reverse, $to, $from)
{
    var deferred = new $.Deferred();

    // Perform any actions or set-up necessary to kick-off
    // your transition here. The only requirement is that
    // whenever the transition completes, your code calls
    // deferred.resolve(name, reverse, $to, $from).

    // Return a promise.
    return deferred.promise();
}

// Register it with jQuery Mobile:

$.mobile.transitionHandlers["myTransition"] = myTransitionHandler;

Once you've registered your handler, you can invoke your transition by placing a data-transition attribute on a link:

<a href="#page2" data-transition="myTransition">Page 2</a>

When the user clicks the link above, your transition handler will be invoked after the page is loaded and it is ready to be shown.

Overriding a CSS Transition With Your Own Handler

As previously mentioned the default transition handler assumes that any transition name other than "none" is a CSS class to be placed on the "from" and "to" elements to kick off a CSS3 animation. If you would like to override one of these built-in CSS transitions, you simply register your own handler with the same name as the CSS page transition you want to override. So for example, if I wanted to override the built-in "slide" CSS transition with my own JavaScript based transition, I would simply do the following:

// Define your transition handler:

function myTransitionHandler(name, reverse, $to, $from)
{
    var deferred = new $.Deferred();

    // Perform any actions or set-up necessary to kick-off
    // your transition here. The only requirement is that
    // whenever the transition completes, your code calls
    // deferred.resolve(name, reverse, $to, $from).

    // Return a promise.
    return deferred.promise();
}

// Register it with jQuery Mobile:

$.mobile.transitionHandlers["slide"] = myTransitionHandler;

Once you do this, anytime the "slide" transition is invoked, your handler, instead of the default one, will be called to perform the transition.

Overriding the Default Transition Handler

The $.mobile.css3TransitionHandler function is the default transition handler that gets invoked when a transition name is used and not found in the $.mobile.transitionHandlers dictionary. If you want to install your own custom default handler, you simply set the $.mobile.defaultTransitionHandler to your handler:

// Define your default transition handler:

function myTransitionHandler(name, reverse, $to, $from)
{
    var deferred = new $.Deferred();

    // Perform any actions or set-up necessary to kick-off
    // your transition here. The only requirement is that
    // whenever the transition completes, your code calls
    // deferred.resolve(name, reverse, $to, $from).

    // Return a promise.
    return deferred.promise();
}

$.mobile.defaultTransitionHandler = myTransitionHandler;

Once you do this, your handler will be invoked any time a transition name is used but not found within the $.mobile.transitionHandlers dictionary.

Clone this wiki locally