Last active
August 29, 2015 13:56
-
-
Save ergoithz/9112265 to your computer and use it in GitHub Desktop.
Micro AJAX snipped with hashbang urls (for browser history) with zero dependencies. Converts every link with 'ajax' class into a ajax link (for gracefully degrading) and only loads data from selected tags (section#content or body) into #content (for ajax using static files).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> | |
<title>Example</title> | |
<script src="uajax.js"></script> | |
</head> | |
<body> | |
<nav> | |
<ul> | |
<li><a class="ajax" href="index.html">Index</a></li> | |
<li><a class="ajax" href="test1.html">Test1</a></li> | |
<li><a class="ajax" href="test2.html">Test2</a></li> | |
</ul> | |
</nav> | |
<section id="content"> | |
<p>Index page</p> | |
</section> | |
<script>window.uajax.start();</script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
window.uajax={}; | |
window.uajax.start=function(){ | |
var links=document.getElementsByTagName("a"), curhash="#!/", baseurl, | |
findmany=function(str, subs, many){ | |
// Return all or given 'many' positions of substring in string | |
var s=0, r=[], l=str.length, m=many||l, p; | |
while((m--)&&(s<l)){ | |
p=str.substring(s).search(subs); | |
if(p==-1) break; | |
r.push((s+=p+1)-1); | |
} | |
return r; | |
}, | |
firstof=function(str, alternatives){ | |
// Return first element of alternatives found in string | |
var minpos=str.length, minchar=0, pos; | |
for(var i=0,l=alternatives.length;i<l;i++){ | |
pos=str.search(alternatives[i]); | |
if((-1<pos)&&(pos<minpos)){ | |
minpos=pos; | |
minchar=i; | |
} | |
} | |
return minchar; | |
}, | |
subpart=function(str, chr){ | |
// Substr with character instead of index | |
return str.substr(str.search(chr)+chr.length); | |
}, | |
tagcontent=function(obj, tagname, id){ | |
// Return content of tag in xml string | |
var starts=findmany(obj, "<"+tagname), | |
endings=findmany(obj, "</"+tagname), | |
salts=[" id=\""+(id||"")+"\"", ">"], | |
pos=id?null:0, epos; | |
if(id) // Move pos to start with given id | |
for(var i=0,l=starts.length;i<l;i++) | |
if(firstof(obj.substr(starts[i]), salts)==0){ | |
pos=i; | |
break; | |
} | |
if(pos===null) return ""; | |
// Find matching ending | |
console.log([starts, endings]); | |
for(var i=0,l=Math.min(starts.length-pos,endings.length);i<l;i++) | |
if(starts[pos+i]>endings[i]) break; | |
epos=(pos+i<starts.length)?undefined:(endings[i-1]-starts[pos]); | |
return subpart(obj.substr(starts[pos],epos), ">"); | |
} | |
ajaxcback=function(ajax){ | |
// Ajax callback | |
var data="", r=unescape(ajax.responseText); | |
if (ajax.readyState==4) | |
data = tagcontent(r, "section", "content") || tagcontent(r, "body"); | |
else{ | |
if(ajax.readyState==404) data="Not found."; | |
else data="XMLHttpRequest:"+ajax.readyState.toString(); | |
} | |
document.getElementById("content").innerHTML = data; | |
}, | |
addevent=function(el, evt, cback){ | |
// Crossbrowser add event | |
if(el.addEventListener) | |
el.addEventListener(evt, cback, false); | |
else if(el.attachEvent) | |
el.attachEvent('on'+evt, cback); | |
}, | |
clickevent=function(evt){ | |
// Click callback | |
var e=evt||window.event; | |
ajaxload(this.href); | |
e.cancelBubble=true; | |
if(e.preventDefault) e.preventDefault(); | |
if(e.stopPropagation) e.stopPropagation(); | |
}, | |
ajaxload=function(loc){ | |
// Load url using ajax | |
var xhr=null; | |
if(XMLHttpRequest) xhr=new XMLHttpRequest(); | |
else if(ActiveXObject) | |
try{xhr=new ActiveXObject("Msxml2.XMLHTTP");} | |
catch(e3){ | |
try{xhr=new ActiveXObject("Microsoft.XMLHTTP");} | |
catch(e2){} | |
} | |
loc=loc.replace(baseurl, "/"); | |
if(loc=="/"){ | |
document.location.hash=""; | |
curhash="#!/"; | |
}else document.location.hash=curhash="#!"+loc; | |
try{ | |
xhr.open("GET", loc.substr(1), true); | |
xhr.onreadystatechange=function(){ajaxcback(xhr);}; | |
xhr.send(null); | |
}catch(e){console.log(e);}; | |
}, | |
checkhash=function(){ | |
// Check if current shebang does not match | |
var h=(document.location.hash||"#!/"); | |
if((h.substr(0,3)=="#!/")&&(h!=curhash)) | |
ajaxload(h.substr(2)); | |
}; | |
baseurl=""+document.location.href; | |
baseurl=baseurl.substr(0, baseurl.length-document.location.hash.length); // remove hash | |
baseurl=baseurl.substr(0, baseurl.lastIndexOf("/")+1); // remove last part | |
// Attach click event on ajax links | |
for(var i=0,l=links.length;i<l;i++) | |
if((links[i].href)&&(links[i].className.indexOf("ajax")>-1)) | |
addevent(links[i], "click", clickevent); | |
// Check hash changes (history) | |
setInterval(checkhash, 500); | |
checkhash(); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment