preface

It has been a long time since I started tossing about typecho. If I don't have anything to write, I can just go to the water tutorial (x
Although there have been many articles on the use of pjax technology for typecho, I still want to write some content and experience of my own jquery pjax

Project address jquery-pjax

text

Introduce resources

First introduce jQuery and jquery ajax in the page

 <script src="path/to/jquery.js"></script> <script src="path/to/jquery.pjax.js"></script>

Note that the version of jQuery introduced is recommended to be 2.0.1 or higher. My jQuery version is 3.3.1, and my jquery Ajax version is 2.0.1
All your Ajax related code should be introduced jquery-pjax.js Of script After label

Basic use

 $(document).pjax(selector, [container], options)
  1. Selector: the selector of the element of the click event to be bound
  2. container: only The selector for the Ajax container.
  3. options:
option Default explain
timeout six hundred and fifty Ajax timeout (milliseconds), forcing the entire page to refresh after timeout
push true Use pushState to add history in the browser
replace false Replace URL address without adding browser history
maxCacheLength twenty Maximum value of container element cache content (times)
version string or function , return the current Ajax version
scrollTo zero The vertical scroll position of the browser scroll bar. Set to false Do not scroll when
type "GET" reference resources $.ajax
dataType "html" reference resources $.ajax
container CSS selector for the replaced content element
url link.href string or function , return the URL of the ajax request response
target link In the ajax event relatedTarget The final value of the attribute
fragment Css selector to extract the content fragment specified in the ajax response content

My code:

 $(document).pjax( 'a[href^="' + THEME_CONFIG.SITE_URL + '"]:not(a[target="_blank"], [no-pjax],a[rel~="nofollow"])',  { container: '#pjax-container', fragment: '#pjax-container', timeout: 8000 })

among THEME_CONFIG.SITE_URL It is the URL address of the site. Please refer to JQuery Reference Manual - Selector

send and complete event

Pjax provides two events that enable us to display some transition animations when refreshing local content, such as NProgress I use now

event parameter explain
pjax:send xhr, options Triggered after the pjax has started clicking through the link
pjax:complete xhr, textStatus, options Triggered after the completion of the ajax response, regardless of the result

Sample code:

 $(document).on('pjax:send', function () { NProgress.start(); }).on('pjax:complete', function () { NProgress.done(); });

Of course, you can use other transition animations

Overloading of some JS

Pjax will only get the data in the container you set each time you request data, so you must reload some specific js functions in the callback function after the end of pjax.
My code: (Some judgments have been simplified and slightly modified to make it easy to read)

 //#Animation of header and # body $('#header').removeClass('slideOutUp').addClass('slideInDown'); $('#body').removeClass('fadeOut').addClass('fadeIn'); fancybox();             // Picture light box effect hitokoto();             // One word recapture lazyload();             // Image lazy loading hljs.init();            // Highlight. js code commentPlus.init();     // Some enhancements to comments, such as facial expressions postOther.init();       // Some enhancements in the article closeNav();             // Close navigation bar /**Overload part of the statistical code comes from QQ blog*/ /** baidu */ if (typeof _hmt !== ' undefined') { _hmt.push(['_trackPageview',  location.pathname + location.search]); } /** google */ if (typeof ga !== ' undefined') { ga('send', 'pageview',  location.pathname + location.search); }

The overload code is written according to the actual situation. The code in different situations is generally different. The above is just an example

Complete code

The following is the complete code of pjax used by my blog, which has been partially modified for easy reading and reference

 var doPjaxStartAction = function () { $("#header").toggleClass('slideOutUp'); $("#body").toggleClass('fadeOut'); $("#wrapper").hide(); } var doPjaxCompleteAction = function () { ('#header').removeClass('slideOutUp').addClass('slideInDown'); $('#body').removeClass('fadeOut').addClass('fadeIn'); fancybox();             // Picture light box effect hitokoto();             // One word recapture lazyload();             // Image lazy loading hljs.init();            // Highlight. js code commentPlus.init();     // Some enhancements to comments, such as facial expressions postOther.init();       // Some enhancements in the article closeNav();             // Close navigation bar /**Overload part of the statistical code comes from QQ blog*/ /** baidu */ if (typeof _hmt !== ' undefined') { _hmt.push(['_trackPageview',  location.pathname + location.search]); } /** google */ if (typeof ga !== ' undefined') { ga('send', 'pageview',  location.pathname + location.search); } } $(document).pjax('a[href^="' + THEME_CONFIG.SITE_URL + '"]:not(a[target="_blank"], [no-pjax],a[rel~="nofollow"])', { container: '#pjax-container', fragment: '#pjax-container', timeout: 8000 }).on('pjax:send', function () { NProgress.start(); doPjaxStartAction(); }).on('pjax:complete', function () { NProgress.done(); doPjaxCompleteAction(); })

Resolve comment can't be replied

stay /var/Widget/Archive.php From line 1720 to line 1792 of the file, you can see the relevant js code of the following comment reply

 $header .=  "<script type=\"text/javascript\"> (function () { window.TypechoComment = { dom : function (id) { return document.getElementById(id); }, create : function (tag, attr) { var el = document.createElement(tag); for (var key in attr) { el.setAttribute(key, attr[key]); } return el; }, reply : function (cid, coid) { var comment = this.dom(cid),  parent = comment.parentNode, response = this.dom('" . $this->respondId . "'), input = this.dom('comment-parent'), form = 'form' == response.tagName ? response : response.getElementsByTagName('form')[0], textarea = response.getElementsByTagName('textarea')[0]; if (null == input) { input = this.create('input', { 'type' : 'hidden', 'name' : 'parent', 'id'   : 'comment-parent' }); form.appendChild(input); } input.setAttribute('value', coid); if (null == this.dom('comment-form-place-holder')) { var holder = this.create('div', { 'id' : 'comment-form-place-holder' }); response.parentNode.insertBefore(holder, response); } comment.appendChild(response); this.dom('cancel-comment-reply-link').style.display = ''; if (null !=  textarea && 'text' == textarea.name) { textarea.focus(); } return false; }, cancelReply : function () { var response = this.dom('{$this->respondId}'), holder = this.dom('comment-form-place-holder'), input = this.dom('comment-parent'); if (null !=  input) { input.parentNode.removeChild(input); } if (null == holder) { return true; } this.dom('cancel-comment-reply-link').style.display = 'none'; holder.parentNode.insertBefore(response, holder); return false; } }; })(); </script> ";

Notice on lines 1739 and 1774:

 $this->respondId

The reason why you cannot reply is that the respondId output is incorrect, because the ID has not been modified when the other page is obtained by Ajax.
So the simpler way is to insert the above code into the comments.php File (also in the container of pjax), so that each time pjax enters a different article, this ID will be output correctly.

other

To enable pjax, you need to Settings ->Comments ->Enable anti garbage protection The check of is cancelled. Here is a plugin for anti spam comments SmartSpam

Postscript

In addition to jquery ajax, here is another recommended project for ajax MoOx/pjax
Compared with the former, the latter has some advantages

  • Not limited to one container
  • It does not depend on jQuery and is very small

This pjax project was also used by me before, but it was replaced by the current one.
Of course, the more famous ones are Instantclick