📜 ⬆️ ⬇️

Creating a single-page ajax application with support for the History API (and without it)

Judging by the comments in this article, the creation of web applications with the possibility of Ajax navigation is an interesting topic for the community and so far few have encountered a similar task. I will talk about its solution using a small library called jQuery-Pjax (or my fork of it).

My motivation: in the project it was necessary to implement an mp3 player that plays independently of the navigation on the site. Next, it was necessary to add browser support without pushState - and I made the fork of the library.

Key Features


Links


Pjax working principle


The basis is separate output and caching of ordinary requests and requests with specific headers. That is, in the controller before displaying the page template, it is necessary to check for the presence of an X-PJAX header, for example, like this:
')
PHP:
if (!isset($_SERVER['HTTP_X_PJAX']) { // here is regular-kind load } else { // here you don't print page layout — just the page } 


Further, an event is suspended on the links, which transfers the navigation control to the javascript (this is the most rosy and unobtrusive implementation - and I don’t see much sense in others). In my case, there is something like:

 $('#pjaxcontainer a:not(.logout-link,.login-link,.login_link,[id*="login_link"],[href*="#"],[target="_blank"],' +'[href$="mp3"],[href$="jpg"],[href$="jpeg"],[href$="gif"],[href$="png"],[href$="doc"],[href$="pdf"])') .pjax('#pjaxcontainer', { timeout: 0 }); 


For form processing we use:

 $('#pjaxcontainer form').live('submit',function(a){ // display loading message $('#loading-shade').show(); if( !$(a.target).attr('action')) a.target = $(a.target).closest('form'); data = $(a.target).serialize(); cont = $('#pjaxcontainer'); $.ajax({ type: "POST", url: $(a.target).attr('action'), data: data, beforeSend : function(xhr) { return xhr.setRequestHeader('X-PJAX','true'); // IMPORTANT }, success: function(msg){ cont.html(msg); $('#loading-shade').hide(); }, error: function(a,b,c) { $('#loading-shade').hide(); } }); a.preventDefault(); return false; }); 


But you, of course, can use a specific class or data-pjax attribute to select links.

There are also two helpful events:
  $('body').bind('start.pjax',function() { setTimeout("$('#loading-shade').hide();",2000); // to be sure that loading message hides $('#loading-shade').show(); }); $('body').bind('end.pjax',function() { $('#loading-shade').hide(); }); 


For more information about Pjax, see README.md on github.

Finishing the hash navigation


The creator of the library was asked several times to add support for hashes, but his position was fundamental ( github.com/defunkt/jquery-pjax/issues/3#issuecomment-986233 , github.com/defunkt/jquery-pjax/issues/3# issuecomment-1353555 , github.com/defunkt/jquery-pjax/issues/3#issuecomment-1354589 ). Therefore, I slightly modified it by adding an automatic transition to #! / Hashes and free conversion of two types of addresses.

However, in my modification it is necessary to specify two parameters:
 $.siteurl = 'http://yousite.com'; $.container = '#pjaxcontainer'; 


Conclusion


Thus, in a few lines of code, we will implement a single-page web application. I would be grateful for comments and any bugtracks.

Your own © defunkt

Thanks Terion for the tip.

image => image

Plans


Work on this project turned out to be extremely informative - because there is something to tell more. In the next article I will write about creating a multifunctional audio-video player with a jPlayer-based playlist (http://jplayer.org/).



Important comments


Devgru, July 12, 2011, 20:43 #

The exclamation mark is a special signal for search engines that this content may be available in other ways. Without it, the hash navigation for the search engine really turns into a black box.

Devgru, July 12, 2011, 23:29 #

Not certainly in that way.
An additional URL is used for processing, see spec and initial initiative .

And yes, it seems like this is just Google.
I did not use this functionality, only read.

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


All Articles