Lifehacker implements URL change with Ajax

I see that Lifehacker can change the URL using AJAX to refresh part of the page. I assume this can be implemented using HTML5 or the history.js plugin, but I think lifehacker does not use any of them.

Does anyone know how they do this? I am new to AJAX and just managed to refresh part of the page using Ajax.


Thanks to @Robin Anderson for the detailed step by step. I tried and it works fine. However, before I can test it in production, I would like to run the code that I have with you. Did I do everything right?

<script type="text/javascript"> var httpRequest; var globalurl; function makeRequest(url) { globalurl = url; /* my custom script that retrieves original page without formatting (just data, no templates) */ finalurl = '/content.php?fname=' + url ; if(window.XMLHttpRequest){httpRequest=new XMLHttpRequest}else if(window.ActiveXObject){try{httpRequest=new ActiveXObject("Msxml2.XMLHTTP")}catch(e){try{httpRequest=new ActiveXObject("Microsoft.XMLHTTP")}catch(e){}}} /* if no html5 support, just load the page without ajax*/ if (!(httpRequest && window.history && window.history.pushState)) { document.href = url; return false; } httpRequest.onreadystatechange = alertContents; alert(finalurl); /* to make sure, content is being retrieved from ajax */ httpRequest.open('GET', finalurl); httpRequest.send(); } /* for support to back button and forward button in browser */ window.onpopstate = function(event) { if (event.state !== null) { document.getElementById("ajright").innerHTML = event.state.data; } else { document.location.href = globalurl; return false; }; }; /* display content in div */ function alertContents() { if (httpRequest.readyState === 4) { if (httpRequest.status === 200) { var stateObj = { data: httpRequest.responseText}; history.pushState(stateObj, "", globalurl); document.getElementById("ajright").innerHTML = httpRequest.responseText; } else { alert('There was a problem with the request.'); } } } </script> 

PS: I don’t know how to insert the code in the comment, so I added it here.

+4
source share
2 answers

It is not a requirement to have markup like HTML5 in order to use the history API in the browser, even if it is an HTML5 function.

One very fast and easy implementation of loading all page transistors using AJAX:

  • Connect all links except when rel = "external" exists for the "ChangePage" function
  • When starting ChangePage, check if the history API is supported in the browser.
  • If the history API is not supported, either click the hash hat, or do a normal full page load as a backup.
  • If the story API is supported:
    • Prevent normal link behavior.
    • Click the new URL in your browser history.
    • Make an AJAX request to the new URL and retrieve its contents.
    • Look at your div content (or similar element) in the answer, take the HTML from this and replace the HTML of the corresponding element on the current page with a new one.

It will be easy to implement, easy to manage caches and work well with Googlebots, the disadvantage is that it is not so “optimized”, and it will have several overheads for answers (compared to a more complicated solution) when changing pages.

It will also have backward compatibility, so older browsers or "visitors without javascript" will simply get normal page loads.

Interesting related links

Edit:

Another thing worth mentioning is that you should not use it with ASP.Net Web Forms applications, likely messing up postback processing.

Adding code:

I have put together a small demo of this feature which you can find here .

It just uses HTML, Javascript (jQuery) and a tiny bit of CSS, I would probably recommend that you test it before using it. But I tested it in Chrome and it seems to work decent.

Some testing that I would recommend is:

  • Test in good browsers, Chrome and Firefox.
  • Test it in an outdated browser like IE7
  • Test it without Javascript enabled (just install Noscript or similarly Chrome / Firefox)

Here is the javascript I used for this, you can find the full source in the demo above.

 /* The arguments are: url: The url to pull new content from doPushState: If a new state should be pushed to the browser, true on links and false on normal state changes such as forward and back. */ function changePage(url, doPushState, defaultEvent) { if (!history.pushState) { //Compatability check return true; //pushState isn't supported, fallback to normal page load } if (defaultEvent != null) { defaultEvent.preventDefault(); //Someone passed in a default event, stop it from executing } if (doPushState) { //If we are supposed to push the state or not var stateObj = { type: "custom" }; history.pushState(stateObj, "Title", url); //Push the new state to the browser } //Make a GET request to the url which was passed in $.get(url, function(response) { var newContent = $(response).find(".content"); //Find the content section of the response var contentWrapper = $("#content-wrapper"); //Find the content-wrapper where we are supposed to change the content. var oldContent = contentWrapper.find(".content"); //Find the old content which we should replace. oldContent.fadeOut(300, function() { //Make a pretty fade out of the old content oldContent.remove(); //Remove it once it is done contentWrapper.append(newContent.hide()); //Add our new content, hidden newContent.fadeIn(300); //Fade it in! }); }); } //We hook up our events in here $(function() { $(".generated").html(new Date().getTime()); //This is just to present that it actually working. //Bind all links to use our changePage function except rel="external" $("a[rel!='external']").live("click", function (e) { changePage($(this).attr("href"), true, e); }); //Bind "popstate", it is the browsers back and forward window.onpopstate = function (e) { if (e.state != null) { changePage(document.location, false, null); } } }); 
+8
source

DOCTYPE does not affect the functions that the page can use.

They probably use the HTML5 history API directly.

0
source

Source: https://habr.com/ru/post/1382152/


All Articles