Asual

Tuesday,
28 Apr 2009

Introducing jQuery Address

I'm happy to announce our first contribution to the jQuery ecosystem. Our brand new project called jQuery Address brings the deep linking functionality to jQuery and hopefully is going to simplify one of the most common tasks for JavaScript developers. In other words it provides an API for creating direct links to specific Ajax states and enables the Back and Forward buttons of the browser.

jQuery Address is a direct port of the SWFAddress library which has become a standard in the Flash world and has been used on many high profile websites. It supports all the major browsers and degrades flawlessly in a small percent of unsupported versions. This first release ships with 2 samples that showcase the different ways to utilize the plugin (API sample) and how to use with jQuery UI (Tabs sample). The next steps we're planning include documentation, SEO samples and integration with the SWFObject plugin.

The work on the plugin started a few months ago but so far I wasn't able to find the time to release it. It's my first serious work that involves jQuery and I'm open for suggestions, critiques and comments. I had great time learning the library and writing the most expressive code ever. The good thing about the plugin is that it has much smaller file size compared to SWFAddress but it also does not target Flash content at this point.

I hope that our experience in this field will be valuable to many jQuery users. The plugin already contains all the improvements included in the upcoming SWFAddress 2.3 which is we're planning to release tomorrow.

Download jQuery Address 1.0

« Previous Post | Next Post »

Comments:

Left by Rich at Mon, 19 Apr 4:15 PM
Thanks for the library. It was a great help with an AJAXy video search we have implemented.

One note/comment/heads up:
There is an embedded bit of logic in the library that will call the Google Analytics functions, trackPageview or urchinTracker. While this makes sense in many cases, it didn't in ours and actually artificially lowered our bounce rate for the page and increased our page view count.
We simply commented out the calls to the Analytics functions.
Left by Ioannis Cherouvim at Mon, 19 Apr 4:15 PM
Superb plugin. Thanks!

Is it possible to deep link using #foo instead of #/foo ?

Thanks
Left by gwk at Mon, 19 Apr 4:15 PM
There is a small bug with the parameter function, when parsing a querysting with the same key for two values (for example '?foo=bar&foo=baz) which is perfectly legal it only returns the first value. By changing the function to the following it will work correcly. (Compatible with $.param and all the jQuery AJAX function data parameters)


parameter: function(param) {
var value = this.value();
var index = value.indexOf('?');
var rerurnvalue = [];
if (index != -1) {
value = value.substr(index + 1);
var params = value.split('&');
var p, i = params.length;
while(i--) {
p = params[i].split('=');
if (p[0] == param)
rerurnvalue.push(p[1]);
}
if(rerurnvalue.length == 1) return rval[0];
if(rerurnvalue.length > 0) return rval;
}
},
Left by gwk at Mon, 19 Apr 4:15 PM
Oops, typo, that obviously should have been 'returnvalue' not 'rerurnvalue'.

btw, I haven't tested it but considering what happened to the code I posted this comment system might be slightly xss vulnerable. (pasting a youtube embed link at least shows up in live comment preview).

Regards,

gwk
Left by dip at Mon, 19 Apr 4:15 PM
nice plugin (still practicing), I'm looking forward to see some seo examples :)
Left by Gwen at Mon, 19 Apr 4:15 PM
When I use both the $.address.init and $.address.change, both callbacks fire on the first page load. Is there a way to make it so that only the function for $.address.init fires on the inital page load, and $.address.change is called every address change there after?

I even copied the exact format from the example pages, inserting my own functions, to now avail.
Left by Tristan at Mon, 19 Apr 4:15 PM
Yes, the code fix shown above by Amir for Google Chrome and cross-domain framing issues is correct. Thanks for the help!
Left by Georg at Mon, 19 Apr 4:15 PM
Hi Rostislav,

Thanks for this gorgeous plugin!

I had an issue with links coming in by AJAX. The magic didn't want to work on those new links.
Changing:
<code> $.fn.address = function (fn) { $(this).click(function() { ...
to
<code> $.fn.address = function (fn) { $(this).live('click',function() { ...
did the trick for me.

I hope it doen't break too much of the magic...

Cheers,
Georg
Left by Mark at Mon, 19 Apr 4:15 PM
Hi, this plugin is great! I'm wondering how to make it ignore external links on the site. I'm using this method to address the links:

var bindBehaviors = function(scope) {
$(function () {
$('a').address();
});
};
bindBehaviors(this);
Left by klucznik at Mon, 19 Apr 4:15 PM
I had a problem in IE6 and 7, the hidden iframe prevented browser from posting a form corectly, I did fix it by changeing this line:

_d.body.innerHTML = '<iframe id="' + ID + '" src="javascript:false;" width="0" height="0"></iframe>' + _d.body.innerHTML;

Into this:

$("body").append('<iframe id="' + ID + '" src="javascript:false;" width="0" height="0"></iframe>');

Basicaly i moved iframe from begining to the end of body (and after the troublesome form)
Left by oj at Mon, 19 Apr 4:15 PM
Hi
I'd like to know if it's possible to use the plugin only if the user click on "previous" or "next" button.
I'd like to manage the site like GMAIL: when you click on a link, it's loading the page, and then the URL change. But when you click on previous or next, the URL change and then the page is loading.
Thx
Left by Doug S. at Mon, 19 Apr 4:15 PM
This is a really cool plugin but there are a few things I'd like to see it to before I use this on a client's website.

First, instead of adding "#..." to the address it can replace part of the string. So, for instance, I could use a REGEX expression to replace "/value1/" with "/value2/".

Second, and this might just be simpler, to replace the entire URL.

Either of these would remove the "#..." from the URL, which would be quite handy. I could possibly work around it if necessary but given the option I'd rather keep my clean URLs.
Left by ab at Mon, 19 Apr 4:15 PM
Hi again,

refering the the post before:

the init() excuts only if it's in the <head> of the page, and I'm trying to call it inside a Object, is ther any solution for that please?

.ab
Left by Rostislav at Mon, 19 Apr 4:15 PM
@gwk
Thanks for the patch. I will try to include it in the next release.

There is known IE loading issue that has been fixed months ago but I haven't found the time to release. Hopefully this will happen very soon.
Left by Rich at Mon, 19 Apr 4:15 PM
Regarding the tracking functionality.
The only reason we wanted to disable it was because it seemed to be calling trackPageview when the page initially loaded, which we don't want. But, we do want it to call trackPageview whenever the $.address.change() is fired, after the initial page load.
Any thoughts?
Left by Ben at Mon, 19 Apr 4:15 PM
I am playing with the SEO example and MAMP. I tested the seo example in Safari with plugins disabled at

http://localhost/seo/

to simulate the experience of an iPhone or Search robot. When I click on a link to About I get this error:

"The requested URL /swfaddress/samples/seo/index.php was not found on this server."

However when I put the seo example in the folder structure:

http://localhost/swfaddress/samples/seo/

Everything works just fine. So my question is, when using
http://localhost/seo/ where is swfaddress/samples/ coming from? What code is setting that?

Thank you!
Left by Rostislav at Mon, 19 Apr 4:15 PM
@jb
Thanks for noticing that. There was a problem with the tabs initialization which should be fixed now and the code became even simpler.

@Mark
Probably you have received my response on Twitter. It's totally up to you to distinguish the external links.

@Yusuf
The plugin should work for forms that create GET queries and I will try to prepare a sample for the next release.
Left by Yusuf Akyol at Mon, 19 Apr 4:15 PM
Hi,
I congratulate you.
Do you plan to add same functionalty for forms?
Best regards...
Left by Max A at Mon, 19 Apr 4:15 PM
Plugin looks great, but is there a way for Internet Explorer to work even if the main page has document.domain set? I'm getting Access is Denied errors when the iframe is written to...

(also there needs to be a support forum)
Left by Rostislav at Mon, 19 Apr 4:15 PM
@Andriy
Thanks for reporting this! We will release an update soon and hopefully this will be fixed.
Left by dgrebb at Mon, 19 Apr 4:15 PM
Howdy,

After working with this wonderful solution for a bit, I realized that the problem jb mentioned above was happening on my site as well. It turns out the fix Left by Rostislav at Sun, 24 May 2:43 PM isn't included in the downloadable project zip.

Copy pasting the jquery from the example page ( http://www.asual.com/jquery/address/samples/tabs/ ) should fix any remaining issues.

Thanks for a fantastic addition to the jQuery plugins :)
Left by Andrew at Mon, 19 Apr 4:15 PM
Sorry the "Deep link" above was meant to be:

<a href="/deep-link" rel="address:/deep-link">Deep link</a>
Left by Gwen at Mon, 19 Apr 4:15 PM
@Rostislav Thanks for you help, but could you show an example? When I use the timeout, nothing happens.
Left by Jason Mixon at Mon, 19 Apr 4:15 PM
Fantastic module. I have one problem that I haven't quite figured out how to overcome. What if I want to access a named anchor within content that has been loaded by ajax? It seems that once the url has been changed with this module named anchors no longer work. Know of any way around this?
Left by Rich at Mon, 19 Apr 4:15 PM
Thanks for that information, Rostislav! I assumed there was probably some way to disable it but couldn't find that information.
Left by James Gibson at Mon, 19 Apr 4:15 PM
Great jQuery plugin. I just incorporated it into a project that I am doing and it is awesome! Thanks for the great work!

James
Left by Chip at Mon, 19 Apr 4:15 PM
Anyone get a version of this working with jquery.noConflict so it can be used with prototype?
Left by Rostislav at Mon, 19 Apr 4:15 PM
@Ben
You should adjust the RewriteBase path in the .htaccess file which is often hidden in OSX. Please, post SWFAddress questions in the appropriate posts.
Left by Holger at Mon, 19 Apr 4:15 PM
Hello,

thanks for coding this jQuery plugin. May be I've got an issue. When I use it with jQuery 1.3.2 and Firebug in Firefox 3.0.10 I get the error "accesext_consoleDump is not defined - if ( !handler.guid )" in line 2447.

I didn't get the error in the examples above, but in the examples of the download package.

Does anyone knows the error? What could I do?
Left by Rab at Mon, 19 Apr 4:15 PM
Hi,
Thank you for this plugin.

It has a weird bug, on IE browsers if you include jquery.address AFTER other javascript files, the code in these files don't work.

did any one had the same problem?

Thanks
Left by Rostislav at Mon, 19 Apr 4:15 PM
@Olivvv
Thanks. You're making a good feature request. Please, implement the functionality in your code for now because there are some other features with higher priority. One of them is the ability to distinguish between internal (link click) or external (back button, direct access) change events.
Left by Yann at Mon, 19 Apr 4:15 PM
I can't make work the change event in IE8. Do you have a fix for that ? Do you plan to release a new version ?
Thanks a lot !
Left by harry000 at Mon, 19 Apr 4:15 PM
Thanks for the awesome plug-in.

I have a problem with IE 7. (the plugin works great in Firefox 3.5 and IE 8). In IE 7, it fails with no javascript error. Firebug in Firefox gives an error "H is undefined" (in jquery code) and seems to happen when trying to bind "init" and "change" event (line 400 of jquery-address js file). Firefox seems to ignore the error and continue, but IE7 breaks on it.

Firebug gives the same error on the "Tab" example too.
Left by Andriy at Mon, 19 Apr 4:15 PM
Hi,

I'm using this great plugin on my current project and it works fine on all browsers -- except Safari v4.0.530.17 (Windows XP Pro SP2).

On a page I have few tabs that display different portion of the same page. In address bar links look like:
help.html#/#tab1
help.html#/#tab2

But in Safari v4 they look a bit different and therefore plugin does not work (the second hash symbol got converted into hex code %23):
help.html#/%23tab1
help.html#/%23tab2

Even if I copy-paste the whole correct url into address bar, Safari "fixing" it before requesting the page.

Is there something that can be done to fix this ?

Any help would be appreciated.
Left by jb at Mon, 19 Apr 4:15 PM
Hi, and thanx for the great tabs example. However it seems like the bookmark functionality doesnt quite work as should. If you click the 'features' tab and bookmark that link in your browser and then open up a new browser tab and goto your bookmark url then the correct tab gets active but the text content is that of tab 'Overview'. The same goes if you hit refresh in your browser.
Left by Madbreaks at Mon, 19 Apr 4:15 PM
I've recently switched from RSH to jQuery Address and it's like a weight has been lifted. Thank you for continuing to push this concept forward in such a clean, usable, documented way!

I have an issue though - when clicking on a link whose href is to a named anchor on the same page, an externalChange event is triggered. This isn't what I was expecting, was expecting change and internalChange only. Perhaps this is by design, but I'm having a difficult time accommodating it, as the event's value (the href) as received by my handler doesn't include the '#', so I'm not sure how to distinguish that type of situation without resorting to some ugly hacks.

Your feedback would be greatly appreciated, and again, thanks for your efforts here!
Left by ab at Mon, 19 Apr 4:15 PM
Hi,

Thank you very much for this port :)

in my page I've put:

$.address.init(function(event){
//do somthing
}).change(function(event){
//do somthing
});
the change() works fine but init() don't excut at all, did any body have the smae problem? or I'm missing something?

thank you for your help
Left by edwin at Mon, 19 Apr 4:15 PM
hello i think it's great but i dont understand how to implement..very very poor description
Left by Rostislav at Mon, 19 Apr 4:15 PM
@Rich
Thanks for the feedback! The tracking functionality can be a little tricky. The recommended way to disable it is to include the script using "jquery.address-1.1.min.js?tracker=null" or to call $.address.tracker(null).
Left by Rostislav at Mon, 19 Apr 4:15 PM
@Holger
This looks like an error caused by an extension.

@Olivvv
I think I saw bind(name, fn || data, fn && data) in the jQuery code and the rest is improvisation.

@ab
Thanks for reporting. I will put it on the list.

@Ioannis
The slash is automatically added when the plugin works in strict mode. You have two ways to disable it and they're described in the docs.
Left by Olivvv at Mon, 19 Apr 4:15 PM
Rostislav,

where did you learn about this ? :

$.each(('init,change').split(','), function(i, name){
_api[name] = function(data, fn){
$($.address).bind(name, fn || data, fn && data);
return this;
};
});


This is really cool !
Left by Amir at Mon, 19 Apr 4:15 PM
Found a bug with Chrome & crossdomain iframe container:
Say that you have an application on Facebook
e.g.: http://apps.facebook.com/myapp

this app has an iframe for your domain
e.g.: http://www.mysite.com

the plugin fails on _getWindow function when calling top.document.
Firefox & Explorer goes to the catch(e) , but Chrome does not.

Solution:
chaning the _getWindow function to check whether top.document is UNDEFINED instead of just calling it.

Complete code:

var _getWindow = function() {
try {
if(top.document!=undefined)
return top;
else
return window;
} catch (e) {
return window;
}
};
Left by Jason Mixon at Mon, 19 Apr 4:15 PM
Scratch that last comment. I just realized i had "return false" associated with the anchor tag. Works as expected :)
Left by Rostislav at Mon, 19 Apr 4:15 PM
@Ravi
Try the development copy of the plugin what can be found in the Source section of the site. Recently we improved the IE8 support by detecting the cases where it works like IE7.
Left by Alen Vokic at Mon, 19 Apr 4:15 PM
For all of you experiencing strange and unexpected top margin on IE7 and maybe other IE's try changing this line:

_d.body.innerHTML = '<iframe id="' + ID + '" src="javascript:false;" width="0" height="0"></iframe>' + _d.body.innerHTML;

into this:

_d.body.innerHTML = '<iframe id="' + ID + '" src="javascript:false;" width="0" height="0" style="position:absolute;top:0px;"></iframe>' + _d.body.innerHTML;

The result might not be satisfying for all cases because position:absolute; but it worked in mine..
Left by edwin at Mon, 19 Apr 4:15 PM
i also need to pass some parametrs to the change function:

$j.address.change(function(event) {
//i need some parameters here
});

how do i do that?
Left by Andrew Buck at Mon, 19 Apr 4:15 PM
Hi, I'm a bit unsure about some of the documentation, so can you give me a bit more detail about what these functions actually do:

$.address.autoUpdate() - autoupdate of what?
$.address.crawling() - in what ways can this plugin affect crawling?
$.address.strict() - aside from the "/" not being present in the fragment, what else will turning this off disable?
$.address.tracker() - in what ways can this plugin affect tracking?
$.address.value() - how does this differ from the hash property?
$.address.wrap() - wrapping of what?!

Also aside from using the automatic way of adding the functionality to links (using links of this structure: Deep link) how else can I manually add this functionality to specific links?

Finally how is the Address function used, is it used to set the fragment manually or called as an event?

Sorry there are a lot of questions but I'm more used to procedural coding and the $ syntax of JQuery is a little different to what I'm used to.

Thanks for your help.

P.S. It might be worth throwing the responses in the documentation too.
Left by Rostislav at Mon, 19 Apr 4:15 PM
@Gwen

Add a listener for the init event only and inside of it add one for the change event with a slight timeout of 100ms.
Left by josh at Mon, 19 Apr 4:15 PM
Very nice plugin! Is there an easy way to use jQuery to fade the content in and out? I can't figure out how to apply my usual methods of supplying show() and hide() arguments to the code.
Left by Rostislav at Mon, 19 Apr 4:15 PM
@oj
The plugin is about having a nice navigation in Ajax websites and it can help you create this Gmail like functionality.
Left by Rostislav at Mon, 19 Apr 4:15 PM
@Georg
Thanks! The patch is already applied and will ship with 1.2.
Left by Olivvv at Mon, 19 Apr 4:15 PM
Hi
this plugin is very elegantly written (IMO deserves a blog post on the coding patterns used).

Would it be possible to distinguish between the loading of new content and the loading of content already visited ?

I tried quickly to explore that with some console.log s in your code, but it could not find this information.

So it seems to me that I have to use an array of the hash s of the visited contents to know if its an already visited content but that there is to no direct way to know if the user has clicked the back button.
Left by Roy Park at Mon, 19 Apr 4:15 PM
I have a problem with IE6.
If html page has SELECT element, there is a problem that IE6 is flashing on the screen

To solve this problem, I changed this line:

Before:
_d.body.innerHTML = '<iframe id="' + ID + '" src="javascript:false;" width="0" height="0"></iframe>' + _d.body.innerHTML;

After:
$(_d.body).prepend('<iframe id="' + ID + '" src="javascript:false;" width="0" height="0"></iframe>');

Why did you use body.innerHTML not jQuery's prepend method?
I think that you had to use body.innerHTML because of another reason.
Left by Ravi at Mon, 19 Apr 4:15 PM
I'm not able to add this in IE8. although it's working great in IE6,IE7, FF and other browsers. But when i have opened website in IE8. The change event of the function is not working. it is not showing anything on change. Please email me the code to add functionality in IE8.
Left by arnotw at Wed, 2 Jun 6:13 PM
Hello,
Very nice plug-in, but I have a problem with lightbox. It doesn't work in a tabs.
(there is no conflict with jquery because it works only in Overview when refreshing)

Is there a solution ?

thx
Left by varun at Mon, 2 Aug 4:24 PM
Thanks for the good work. I love this plugin.
One quick question.
I have the following event attached to a div.
On click of div, its ID is updated in the address and the address change callback makes an ajax request.
Now if I click the div again, nothing will happen. This is a bit annoying. I want the callback to be fired every time I click the div.
Is there a way to achieve this? Am I missing something?
Left by Rostislav at Mon, 2 Aug 4:29 PM
@varun
Add a click event to your div and change the address manually. Something like:
$('#container').click(function(e) {
$.address.value('/container');
});
Left by Victor at Fri, 27 Aug 12:41 AM
Thanks for the great plug-in.
I use the plug-in to page through search results but I am having issues with IE7.

For example I can have 3 pages of search results. When I click on a record that is on the 3rd page of results I go to the record details page. When I click back button I go back to page 3 of the search results. When I click back button again I go to the 2nd page of search results. This is the behavior I want.

For some reason in Internet Explorer 7 (IE7) when I click back to the search results I go to page 3 but when I click back button again I go to the previous page and not page 2 of search results.

Am I doing something wrong? And am I the only one that dislikes IE?



on all browsers but
Left by Alexandros at Thu, 27 Jan 3:25 PM
I am using version 1.2.2 of the Address Plugin and I have an issue with IE7.

I am viewing a list of products (which were fetched with AJAX) and I click on one product and the product-detail page loads. Then I click the browser's back button in order to return to the list and nothing happens. I click on back again and still nothing. I click for a third time and it finally works. It always works on the third click. In all other scenarios the back button works great with the first try.

Has anyone ever encountered something like this before or has any clue as to what may be causing it?
Left by Anze at Mon, 7 Mar 2:57 PM
If you set addres to some specific characters, that must be converted like ŠČĆŽĐ -> into %C5 or %D3 the change event fires twice. for both versions.
Left by Bob at Thu, 21 Apr 11:49 PM
I think there's a bug in jQuery Address. Titles are not restored when the back button is hit. I read your source code. It seems like that $.address.title is only updating document.title at next timeout interval. Titles were not saved in the history for back button even though title shows good in the pop-up list of back button.

$.address.value("/pub/author");
$.address.title("Author Index.");
$.address.update();

later,
$.address.value("/pub/subject");
$.address.title("Subject Index.");
$.address.update();

when back button is clicked,
it came to /pub/author but title is unchanged ("Subject Index.")
Left by Thien at Wed, 15 Jun 1:15 AM
How come the downloaded zip file jquery.address-1.4.zip, viewing the tabs sample the features and extras link loads no text at all when viewing in Google Chrome Browser on mac verison 12.0.742 and Firefox 3.6 on Mac. It works fine in Safari though.
Left by Eiran at Wed, 14 Dec 4:17 PM
Hey Rostislav great plugin! thanks for your work!

I'm currently using it in a ajax heavy web app that I'm building and I was wondering if it's possible to remove the # character from the address so rather than having domain.com/#/settings/section it would just be domain.com/settings/section

I remember using the jquery history plugin on another project years ago and it had an option to set a custom # character, or I may have hacked around removing it all together. I haven't looked at an unminified version of your code yet, but would this be hard to do? or do you know if anyone has made this modification already? or would you mind if I did? :)

Basically our site only has deep-linked urls, and apart from that its just one page, so there doesn't need to be any cases for regular urls.
Left by Rostislav at Wed, 14 Dec 4:32 PM
@Eiran

A custom character is not possible without page refresh but you can now completely remove it in modern browsers that support HTML5 pushState.
Left by Bogarts at Wed, 13 Jun 9:17 AM
Hello Rotislav,

I was wondering how do I return a 404 error if the url is not found?

http://somesite.com/#contact <-- correct url would show contact page

http://somesite.com/#contat <-- incorrect url should show 404 page

How do i check this?

Projects

Syndication

Blog Search

Blog Categories

Blog posts

Recommended sites