Permalink
Browse files

edits

  • Loading branch information...
1 parent 252b9d7 commit df22bd793e52b19bbcaf00b62093b7e59b3f78ca @defunkt committed Dec 14, 2012
Showing with 97 additions and 69 deletions.
  1. +97 −69 README.md
View
@@ -23,10 +23,59 @@
## pjax = pushState + ajax
-pjax loads HTML from your server into the current page without a full reload. It's ajax with real permalinks, page titles, and a working back button that fully degrades.
+pjax is a jQuery plugin that uses ajax and pushState to deliver a fast browsing experience with real permalinks, page titles, and a working back button.
+
+pjax works by grabbing html from your server via ajax and replacing the content of a container on your page with the ajax'd html. It then updates the browser's current url using pushState without reloading your page's layout or any resources (js, css), giving the appearance of a fast full page load. But really it's just ajax and pushState. For [browsers that don't support pushState][compat] pjax fully degrades.
pjax enhances the browsing experience - nothing more.
+## Overview
+
+pjax is not fully automatic. You'll need to setup and designate a containing element on your page that will be replaced when you navigate between pages.
+
+Consider the following page.
+
+``` html
+<!DOCTYPE html>
+<html>
+<head>
+ <!-- styles, scripts, etc -->
+</head>
+<body>
+ <h1>My Site</h1>
+ <div class="container" id="pjax-container">
+ Go to <a href="/page/2">next page</a>.
+ </div>
+</body>
+</html>
+```
+
+We want pjax to use ajax to grab the url `/page/2` then replace `#pjax-container` with what it gets back. No styles or scripts will be reloaded and even the h1 can stay the same - we just want to change the `.container` element.
+
+We do this by telling pjax to attach to `a` tags and to replace the content in `#pjax-container` with the ajax response from the `a` tag's href:
+
+``` javascript
+$(document).pjax('a', '#pjax-container')
+```
+
+Now when someone in a pjax-compatible browser clicks "next page" the content of `#pjax-container` will be replaced with the body of `/pjax/2`.
+
+Magic! Almost. You still need to configure you server to look for pjax requests then send back pjax-specific content.
+
+The pjax ajax request sends an `X-PJAX` header so in this example (and in most cases) we return a page without a layout to any requests with that header.
+
+Here's what it might look like in Rails:
+
+``` ruby
+def index
+ if request.headers['X-PJAX']
+ render :layout => false
+ end
+end
+```
+
+If you'd like a more automatic solution than pjax for Rails check out [Turbolinks](https://github.com/rails/turbolinks).
+
## Installation
### bower
@@ -47,7 +96,7 @@ Or add `jquery-pjax` to your apps `component.json`.
### standalone
-Since theres only one file, you can just download it directly into your apps public directory. Just be sure to have jQuery loaded first.
+pjax can be downloaded directly into your app's public directory - just be sure you've loaded jQuery first.
```
curl -O https://raw.github.com/defunkt/jquery-pjax/master/jquery.pjax.js
@@ -57,89 +106,69 @@ curl -O https://raw.github.com/defunkt/jquery-pjax/master/jquery.pjax.js
## Dependencies
-Requires jQuery 1.7.x and higher.
+Requires jQuery 1.7.x or higher.
## Compatibility
-pjax only works with [browsers that support the `history.pushState` API](http://caniuse.com/#search=pushstate). However, there is a fallback mode for browsers that don't. `$.fn.pjax` calls will be a no-op and `$.pjax` will hard load the given url. This mode targets the browser requirements of the jQuery version being used.
+pjax only works with [browsers that support the `history.pushState` API][compat]. When the API isn't supported pjax goes into fallback mode: `$.fn.pjax` calls will be a no-op and `$.pjax` will hard load the given url. This mode targets the browser requirements of the jQuery version being used.
For debugging purposes, you can intentionally disable pjax even if the browser supports `pushState`. Just call `$.pjax.disable()`. To see if pjax is actually supports `pushState`, check `$.support.pjax`.
## Usage
-pjax is not fully automatic. You'll need to setup and designate a containing element on your page that will be replaced when you navigate between pages.
-
-Consider the following page.
-
-``` html
-<!DOCTYPE html>
-<html>
-<head>
- <!-- styles, scripts, etc -->
-</head>
-<body>
- <h1>My Site</h1>
- <div class="container" id="pjax-container">
- Go to <a href="/page/2">next page</a>.
- </div>
-</body>
-</html>
-```
-
-pjax speeds up page loads by cutting out parts of the page that stay the same. If we want to load `/page/2`, its using the same styles and scripts, so we can skip those. And it actually has the same `<h1>` header. We can skip that too. So, we actually only need to load the new content that changes inside the `.container` element.
-
-So our pjax request only makes an ajax request that gets that new inner contents, and just replaces that element.
-
-Almost magic. Well, you'll need to configure you server to know about pjax requests and only send back that content. If you'd like a more automatic solution, check out [Turbolinks](https://github.com/rails/turbolinks).
-
### `$.fn.pjax`
-The most basic thing to get started with is
+Let's talk more about the most basic way to get started:
``` javascript
-$(document).pjax('a', '#pjax-container');
+$(document).pjax('a', '#pjax-container')
```
-This will enable pjax on all links (probably not what you'll actually want) and designate the container as `#pjax-container`.
+This will enable pjax on all links and designate the container as `#pjax-container`.
-If you are migrating an existing site, you probably can't just enable pjax everywhere just yet. So try annotating links that do work with pjax with `data-pjax`. Then use `'a[data-pjax]'` as your selector.
+If you are migrating an existing site you probably don't want to enable pjax everywhere just yet. Instead of using a global selector like `a` try annotating pjaxable links with `data-pjax`, then use `'a[data-pjax]'` as your selector.
-Or try this selector thats matches any `<a data-pjax href=>` link and any link inside a container like `<div data-pjax><a href=>`.
+Or try this selector thats matches any `<a data-pjax href=>` links inside a `<div data-pjax>` container.
``` javascript
-$(document).pjax('[data-pjax] a, a[data-pjax]', '#pjax-container');
+$(document).pjax('[data-pjax] a, a[data-pjax]', '#pjax-container')
```
-When invoking `$.fn.pjax`, theres a few different argument styles you can pass in.
+When invoking `$.fn.pjax` there are a few different argument styles you can use:
+
+1. `$(document).pjax(delegation selector, options object)`
+2. `$(document).pjax(delegation selector, container selector, options object)`
-1. The first argument will always be a `String` selector used for delegation.
+In other words:
+
+1. The first argument must always be a `String` selector used for delegation.
2. The second argument can either be a `String` container selector or an options object.
-3. If theres three arguments, the second will be used as the container and the third will be the options object.
+3. If there are three arguments the second must be the `String` container selector and the third must be the options object.
### `$.pjax.click`
-Is a lower level function used by `$.fn.pjax` itself. It allows you to get a little more control over the pjax event handling.
+This is a lower level function used by `$.fn.pjax` itself. It allows you to get a little more control over the pjax event handling.
-This example uses the current click context to set an ancestor as the container.
+This example uses the current click context to set an ancestor as the container:
``` javascript
if ($.support.pjax) {
$(document).on('click', 'a[data-pjax]', function(event) {
- var container = $(this).closest('[data-pjax-container]');
- $.pjax.click(event, {container: container});
- });
+ var container = $(this).closest('[data-pjax-container]')
+ $.pjax.click(event, {container: container})
+ })
}
```
-**NOTE** The explicit `$.support.pjax` guard. Since we aren't using `$.fn.pjax`, we should avoid binding this event handler unless the browser is actually going to use pjax.
+**NOTE** Use the explicit `$.support.pjax` guard. We aren't using `$.fn.pjax` so we should avoid binding this event handler unless the browser is actually going to use pjax.
### `$.pjax.submit`
-Submits a form via pjax. This function is still considered experimental, but give it a shot!
+Submits a form via pjax. This function is experimental but GitHub uses it on [Gist][gist] so give it a shot!
``` javascript
$(document).on('submit', 'form[data-pjax]', function(event) {
- $.pjax.submit(event, '#pjax-container');
+ $.pjax.submit(event, '#pjax-container')
})
```
@@ -149,14 +178,14 @@ Manual pjax invocation. Used mainly when you want to start a pjax request in a h
``` javascript
function applyFilters() {
- var url = urlForFilters();
- $.pjax({url: url, container: '#pjax-container'});
+ var url = urlForFilters()
+ $.pjax({url: url, container: '#pjax-container'})
}
```
### Events
-No matter which way you invoke pjax, it will fire the following events.
+pjax fires a number of events regardless of how its invoked.
All events are fired from the container, not the link was clicked.
@@ -176,24 +205,24 @@ This pair events fire anytime a pjax request starts and finishes. This includes
* `pjax:error` - Fired after the pjax request fails. Returning false will prevent the the fallback redirect.
* `pjax:timeout` - Fired if after timeout is reached. Returning false will disable the fallback and will wait indefinitely until the response returns.
-`send` and `complete` are a good pair of events to use if you are implementing a loading indicator. They'll only be triggered if an actual request is made, not if its loaded from cache.
+`send` and `complete` are a good pair of events to use if you are implementing a loading indicator. They'll only be triggered if an actual request is made, not if it's loaded from cache.
``` javascript
$(document).on('pjax:send', function() {
- $('#loading').show();
-});
+ $('#loading').show()
+})
$(document).on('pjax:complete', function() {
- $('#loading').hide();
-});
+ $('#loading').hide()
+})
```
-Another protip would be disabling the fallback timeout behavior if a spinner is being shown.
+Another protip: disable the fallback timeout behavior if a spinner is being shown.
``` javascript
$(document).on('pjax:timeout', function(event) {
// Prevent default timeout redirection behavior
- event.preventDefault();
-});
+ event.preventDefault()
+})
```
### Server side
@@ -210,37 +239,39 @@ end
An `X-PJAX` request header is set to differentiate a pjax request from normal XHR requests. In this case, if the request is pjax, we skip the layout html and just render the inner contents of the container.
+Check if your favorite server framework supports pjax here: https://gist.github.com/4283721
+
### Legacy API
Pre 1.0 versions used an older style syntax that was analogous to the now deprecated `$.fn.live` api. The current api is based off `$.fn.on`.
``` javascript
-$('a[data-pjax]').pjax('#pjax-container');
+$('a[data-pjax]').pjax('#pjax-container')
```
Expanded to
``` javascript
$('a[data-pjax]').live('click', function(event) {
- $.pjax.click(event, '#pjax-container');
-});
+ $.pjax.click(event, '#pjax-container')
+})
```
The new api
``` javascript
-$(document).pjax('a[data-pjax]', '#pjax-container');
+$(document).pjax('a[data-pjax]', '#pjax-container')
```
Which is roughly the same as
``` javascript
$(document).on('click', 'a[data-pjax]', function(event) {
- $.pjax.click(event, '#pjax-container');
-});
+ $.pjax.click(event, '#pjax-container')
+})
```
-**NOTE** That the new api gives you control over the delegated element container. `$.fn.live` always bound to `document`. This is what you still want to do most of the time.
+**NOTE** The new api gives you control over the delegated element container. `$.fn.live` always bound to `document`. This is what you still want to do most of the time.
## Contributing
@@ -258,8 +289,5 @@ $ ruby test/app.rb
$ open http://localhost:4567/
```
-## See Also
-
-* Rails - [pjax_rails](https://github.com/rails/pjax_rails)
-* Django - [django-pjax](https://github.com/jacobian/django-pjax)
-* Turbolinks - [turbolinks](https://github.com/rails/turbolinks)
+[compat]: http://caniuse.com/#search=pushstate
+[gist]: https://gist.github.com/

0 comments on commit df22bd7

Please sign in to comment.