Load new content via AJAX and change the URL
Agaric wanted to know how to have a photo album where pictures would load when selected, without re-loading the rest of the page. The goal is to have the chosen picture load (with JQuery effects and any other coolness without a full page refresh) but to also have the URL in the address bar updates so people have a unique link back to the image.
Facebook does this, and the next time I was catching up on my friends' new album additions at 4 a.m. on a Sunday morning, I had to view source and see what was going on.
What looks like the key javascript code is copied below.
Indeed, the whole album page in the first place is loaded by AJAX– viewing source shows not the name of the album, or the Photo X of XX text, nor the Back to Album link, nor the Previous and Next buttons.
I'm pretty sure the code we care most about is the Javascript href.replace function, that it is where the URI is updated to match the AJAX-loaded page content.
<script type="text/javascript">
//<![CDATA[
(function(href) { var uri_re = /^(?:(?:[^:\/?#]+):)?(?:\/\/(?:[^\/?#]*))?([^?#]*)(?:\?([^#]*))?(?:#(.*))?/; href.replace(uri_re, function(all, path, query, frag) { if (frag) { var dst, src = path + (query ? '?' + query : ''); if (frag.charAt(0) == '/') { dst = frag.replace(/^\/+/, '/'); } else if (/&|=/.test(frag)) { var q = {}; var m = frag.match(/([^#]*)(#.*)?/); var arr = (query||'').split('&').concat((m[1]||'').split('&')); for (var i=0, length=arr.length; i<length; i++) { var t = arr[i].split('='); if (t.length && t[0] != '') { q[t[0]] = t[1]; } } var s = []; for (var i in q) { s.push(i+ (q[i]?'='+q[i]:'')); } dst = path+'?'+s.join('&')+(m[2]||''); } if (dst && dst != src) { window.location.replace(dst); } } }); })(window.location.href);Env={quickling_inactive_page_regex:"^\\\/(election08\\\/|logout\\.php|help\\.php|photos\\\/|ac\\.php|ajax\\\/emu\\\/h\\.php|ext\\\/|ads\\\/create\\\/|feeds\\\/|.+(\\?|&)fb95_opt_(in|out)|intern\\\/(?!example\\\/quickling))",method:"GET",dev:0,start:(new Date()).getTime(),ps_limit:5,ps_ratio:4,svn_rev:134874,static_base:"http:\/\/static.ak.fbcdn.net\/",ecdc_page_regex:"^\\\/(safe_image\\.php|ajax\\\/perf\\.php|profile\\.php|home\\.php|photo\\.php|album\\.php|photo_search\\.php|photos\\.php|wall\\.php|friends\\\/ajax\\\/filters\\.php|friends\\\/ajax\\\/friends\\.php|friends\\\/ajax\\\/selector\\.php|group\\.php|groups\\.php|friends\\\/$)"}; var onloadRegister = window.onloadRegister || function(h) { onloadhooks.push(h); }; var onloadhooks = window.onloadhooks || []; var onafterloadRegister = window.onafterloadRegister || function(h) { onafterloadhooks.push(h); }; var onafterloadhooks = window.onafterloadhooks || []; function wait_for_load(element, e, f) { f = bind(element, f, e); if (window.loaded) { return f(); } switch ((e || event).type) { case 'load': onloadRegister(f); return; case 'click': if (element.original_cursor === undefined) { element.original_cursor = element.style.cursor; } if (document.body.original_cursor === undefined) { document.body.original_cursor = document.body.style.cursor; } element.style.cursor = document.body.style.cursor = 'progress'; onafterloadRegister(function() { element.style.cursor = element.original_cursor; document.body.style.cursor = document.body.original_cursor; element.original_cursor = document.body.original_cursor = undefined; if (element.tagName.toLowerCase() == 'a') { var original_event = window.event; window.event = e; var ret_value = element.onclick.call(element, e); window.event = original_event; if (ret_value !== false && element.href) { window.location.href = element.href; } } else if (element.click) { element.click(); } }); break; } return false; }; function bind(obj, method ) { var args = []; for (var ii = 2; ii < arguments.length; ii++) { args.push(arguments[ii]); } var fn = function() { var _obj = obj || (this == window ? false : this); var _args = args.slice(); for (var jj = 0; jj < arguments.length; jj++) { _args.push(arguments[jj]); } if (typeof(method) == "string") { if (_obj[method]) { return _obj[method].apply(_obj, _args); } } else { return method.apply(_obj, _args); } }; if (typeof method == 'string') { fn.name = method; } else if (method) { if (method.name) { fn.name = method.name; } fn.toString = function() { return 'bound<'+method.toString()+'>'; } } return fn; }; function goURI(uri) { uri = uri.toString(); if (window.PageTransitions && PageTransitions.isInitialized()) { PageTransitions.go(uri); } else if (window.location.href == uri) { window.location.reload(); } else { window.location.href = uri; } } var PrimordialBootloader = window.PrimordialBootloader || { loaded : [], done : function(names) { PrimordialBootloader.loaded.push(names); } }; var Bootloader = window.Bootloader || { done : PrimordialBootloader.done };document.cookie = "cavalry_transit_start_time=; expires=Mon, 26 Jul 1997 05:00:00 GMT; path=\/; domain=.facebook.com";
//]]>
</script>
Comments
Post new comment