jQuery BBQ leverages the HTML5
hashchange event to allow simple, yet powerful bookmarkable #hash history. In addition,
jQuery BBQ provides a full .deparam() method, along with both hash state
management, and fragment / query string parse and merge utility
methods.
This plugin and the
jQuery urlInternal plugin supersede the URL Utils plugin.
- Release v1.2.1
- Tested with jQuery 1.3.2, 1.4.1, 1.4.2 in Internet Explorer 6-8, Firefox 2-3.7, Safari 3-4, Chrome 4-5, Opera 9.6-10.1, Mobile Safari 3.1.1.
- Download Source, Minified (4.0kb)
- Follow the project on GitHub project page or report a bug!
- View Full Documentation
- View Unit Tests
- Examples: basic hashchange, advanced hashchange, jQuery UI Tabs history & bookmarking, jQuery.deparam
- Translations: Belorussian
Note: If you’re using jQuery 1.3.2 or earlier and need BBQ to merge query string or fragment params containing
[]
, you’ll want to include the
jQuery 1.4 .param
method in your code.
Also, my article
Cooking BBQ: the original recipe gives a history of jQuery BBQ along with some plugin authoring guidelines, if you’re interested.
What jQuery BBQ allows you to do:
While this brief overview will give you the broad strokes, for specifics you should look at the the basic examples below, read
the documentation, and check out the full examples listed above.
- Deserialize any params string, the document query string or fragment
into an object, including the new jQuery.param format (new in jQuery
1.4, read more here). (example)
- Merge any URL plus query string or fragment params—in an object,
params string or second URL (including the current document
location)—into a new URL.
- Update the “URL attribute” (ie.
a[href]
, img[src]
, form[action]
,
etc) in multiple elements, merging any URL plus query string or
fragment params—in an object, params string or second URL (including the
current document location)—into a new URL, which is then set into that
attribute.
- Push (and retrieve) bookmarkable, history-enabling “state” objects
or strings onto the document fragment, allowing cross-browser back- and
next-button functionality for dynamic web applications (example 1, example 2, example 3)
- Bind event handlers to a normalized, cross-browser hashchange event (example 1, example 2, example 3)
jQuery BBQ community
Have you used jQuery BBQ in an project, website, article or tutorial?
Let me know, and I’ll mention it here!
Projects or websites using jQuery BBQ
Articles or tutorials featuring jQuery BBQ
Why BBQ? AKA: Why “history” and “deparam” together?
Imagine three scenarios. Now, imagine a
star wipe…
The single widget
In the first scenario, you’ve got a single widget on the page. Maybe
the page is the widget, whatever. Either way, things are so simple that
every history plugin can do this (including jQuery BBQ):
<Widget> Yo, hash, update the state with this string.
<Hash> No prob, dude, done. Sure, your state takes up the whole hash, but what do you care, you’re the only widget on the page!
<Widget> But I’m so lonely.
<Hash> Tough luck, kid. There’s only room in this hash for one state.
Multiple widgets, rough-and-tumble
In the next scenario, you’ve got multiple widgets on the page. And
unfortunately, because the history plugin developer didn’t provide an
easy way to manage multiple, separate, individual states simultaneously,
your widgets need to be somewhat aware of each other’s existence, so
they don’t accidentally erase each other’s state in the hash:
<Widget> Yo, hash.. I need to update my state parameters. Whatcha got in there?
<Hash> A string representation of your state, plus maybe some others, I’m not sure. Whatever. Here ya go!
<Widget> Wow, that sure contains a lot of stuff I don’t care about.. But a job’s a job, right?
<Widget> So, first let me figure out where my
parameters are. Ok, right.. Wait! I think some other widget’s parameters
are in here too! Ok. Let’s see, add this in there, carry the one..
great, that seems to be working now.
<Widget> Well, hash, here’s the whole new state. I
inserted my parameters in there next to all the other parameters that
were there. Or maybe i didn’t. I dunno, it probably works.
<Widget2> Are you telling me I’ve got to do all that too? 404 dudes, I quit.
Multiple widgets, with some tasty BBQ sauce
In this final scenario, while there are multiple widgets on the same
page, each one can get and set its own state very easily because the
history plugin can deparameterize any fragment-based params string into
its component parts easily, then merge replacement params in, and
update:
<Widget> Yo, hash, update my state parameters.
<Hash> No prob, dude, done. And you didn’t even
have to know about that other widget’s parameter, I just merged them in
there for you.
<Widget> There’s another widget?
<Widget2> Huh? Did someone say my name?
In case you hadn’t guessed, jQuery BBQ helps you do all this the easy way.
Examples
jQuery.deparam
In the following examples,
jQuery.deparam
is used to deserialize params strings generated with the built-in
jQuery.param
method. Check out the
jQuery.deparam example page and
documentation for more information.
01.
02.
03.
var
myStr = $.param({ a:1, b:2, c:
true
, d:
"hello world"
});
04.
05.
06.
07.
var
myObj = $.deparam( myStr );
08.
09.
10.
11.
var
myObj = $.deparam( myStr,
true
);
12.
13.
14.
15.
var
myObj = $.deparam(
"a[]=1&a[]=2&b[c][]=3&b[d]=4"
,
true
);
jQuery.deparam with query string and fragment
The
jQuery.deparam.querystring
and
jQuery.deparam.fragment
methods can be used to parse params strings out of any URL, including
the current document. Complete usage information is available in the
documentation.
01.
02.
var
myObj = $.deparam.querystring();
03.
04.
05.
var
myObj = $.deparam.fragment();
06.
07.
08.
09.
var
myObj = $.deparam.querystring(
"/foo.php?a=1&b=2&c=hello#test"
);
10.
11.
12.
13.
var
myObj = $.deparam.fragment(
"/foo.php?test#a=3&b=4&c=world"
);
Parsing the query string or fragment from a URL
The
jQuery.param.querystring
and
jQuery.param.fragment
methods can be used to return a normalized query string or fragment
from the current document or a specified URL. Complete usage information
is available in the
documentation.
01.
02.
03.
var
qs = $.param.querystring();
04.
05.
06.
07.
var
hash = $.param.fragment();
08.
09.
10.
11.
var
qs = $.param.querystring(
"/index.php?a=1&b=2&c=3#hello-world"
);
12.
13.
14.
15.
var
hash = $.param.fragment(
"/index.php?a=1&b=2&c=3#hello-world"
);
URL building, using query string and fragment
The
jQuery.param.querystring
and
jQuery.param.fragment
methods can also be used to merge a params string or object into an
existing URL. Complete usage information and merge options are available
in the
documentation.
01.
var
url =
"http://example.com/file.php?a=1&b=2#c=3&d=4"
,
02.
paramsStr =
"a=5&c=6"
,
03.
paramsObj = { a:7, c:8 };
04.
05.
06.
07.
var
newUrl = $.param.querystring( url, paramsStr );
08.
09.
10.
11.
var
newUrl = $.param.querystring( url, paramsObj );
12.
13.
14.
15.
var
newUrl = $.param.fragment( url, paramsStr );
16.
17.
18.
19.
var
newUrl = $.param.fragment( url, paramsObj );
20.
21.
22.
23.
var
newUrl = $.param.fragment(
"index.php"
,
"/path/to/file.php"
, 2 );
URL building in elements with “URL attributes”
The
jQuery.fn.querystring
and
jQuery.fn.fragment
methods are used to merge a params string or object into an existing
URL, in the appropriate selected elements’ “URL attribute” (ie.
a[href]
,
img[src]
,
form[action]
,
etc). Complete usage information and merge options, as well as a list
of all elements’ default “URL attributes” are available in the
documentation.
01.
02.
03.
$(
"a"
).querystring({ a:1, b:2 });
04.
05.
06.
07.
$(
"a"
).querystring(
"a=1&b=2"
, 2 );
08.
09.
10.
11.
$(
"a"
).fragment(
"new-fragment"
, 2 );
12.
13.
14.
15.
16.
var
qsObj = $.deparam.querystring();
17.
delete
qsObj.foo;
18.
$(
"a, form"
).querystring( qsObj );
History & bookmarking via hashchange event
jQuery BBQ leverages the
hashchange event plugin to create a normalized, cross-browser
window.onhashchange
event that enables very powerful but easy to use location.hash state / history and bookmarking. Check out the
basic hashchange,
advanced hashchange and
jQuery UI Tabs history & bookmarking examples, as well as the
documentation for more information.
01.
02.
03.
04.
$(
function
(){
05.
06.
07.
08.
09.
$(
"a"
).click(
function
(){
10.
var
href = $(
this
).attr(
"href"
);
11.
12.
13.
$.bbq.pushState({ url: href });
14.
15.
16.
return
false
;
17.
});
18.
19.
20.
$(window).bind(
"hashchange"
,
function
(e) {
21.
22.
var
url = $.bbq.getState(
"url"
);
23.
24.
25.
26.
27.
$(
"a"
).each(
function
(){
28.
var
href = $(
this
).attr(
"href"
);
29.
30.
if
( href === url ) {
31.
$(
this
).addClass(
"current"
);
32.
}
else
{
33.
$(
this
).removeClass(
"current"
);
34.
}
35.
});
36.
37.
38.
});
39.
40.
41.
42.
43.
$(window).trigger(
"hashchange"
);
44.
});
If you have any non-bug-related feedback or suggestions, please let
me know below in the comments, and if you have any bug reports, please
report them in the
issues tracker, thanks!
I want to thank Paul Irish and Yehuda Katz for all their help refining the jQuery BBQ API, as well as Brandon Aaron for explaining parts of the jQuery.event.special API for me and providing me the example code on which I based the hashchange event plugin. I also want to thank everyone in the #jquery IRC channel on irc.freenode.net for all their suggestions and enthusiasm!