How to add Pjax to a matery theme
Pjax benefits
- Reduce the pressure on the server On demand request, only part of the content of the page needs to be loaded each time, instead of repeatedly loading some public resource files and unchanged page structure, which greatly reduces the amount of data requests, reduces the bandwidth and performance pressure on the server, and greatly improves the loading speed of the page.
- Optimize page Jump experience After using pjax, only some pages are refreshed, the switching effect is more smooth, and excessive animation can be customized, which makes the experience more comfortable when waiting for the page to load.
I know what you care about is the tutorial, not these wordy nonsense. Here is the text
course
Basic understanding
The use of Pjax can change the content of Main on the basis of keeping Nav Header Footer unchanged (applicable to subjects with relatively simple page structure)

step
New pjax ejs
In_ Create a new pjax in the widget directory EJS file
<%if(theme.pjax){%> <script type="text/javascript"> $.getScript("https://cdn.jsdelivr.net/npm/pjax/pjax.min.js",loadPjax) function loadPjax(){ var pjax = new Pjax({ selectors: [ "head title", 'head meta[name="keywords"]', 'head meta[name="description"]', "main#main_wrap" ], cache: true, cacheBust: false }); } // When Pjax request error, jump to page 404 document.addEventListener('pjax:error', (err) => { if (err.request.status === 404) { pjax.loadUrl('/404.html') } }) </script> <%}%>
Add container
Find layout EJE sets a < main > label for <% - body% >
<main id="main_wrap"> <%- body %> </main>
Introducing pjax ejs
Find layout EJS is added at the bottom (there is no need to load pjax first)
<%- partial('_widget/pjax') %>
Add pjax switch
In themes\_ config. Add in YML
pjax: true
bug resolution
Because Pjax will cause the functions in the container not to be overloaded, it is necessary to overload the functions
Only overload methods are provided here, and they will not be demonstrated one by one
Partial modification page
Due to the time problem, only some ejs contents that need to be modified are provided for reference
- Comment page EJS (I use valine, so I need to modify the valine.ejs page)
- Google statistics page (Google Analytics. EJS)
- Article directory (post-detail-toc.ejs)
- Talk about the page (arttalk. EJS)
- Tag wordcloud (tag wordcloud. EJS)
- categories radar chart (category radar. EJS)
- Statistics of Archives (post-calendar.ejs)
- Statistical chart of page (about) (post charts. EJS)
Welcome to submit the missing bug
Take the tags page as an example
When you click on the tags page from the home page after the above steps, an error will be reported

Open tags ejs this page consists of tag cloud and tag wordcloud ejs, so you need to see where the jQCloud function appears on these two ejs pages

Find the bug and modify the original page
<link rel="stylesheet" type="text/css" href="<%- theme.jsDelivr.url %><%- url_for(theme.libs.css.jqcloud) %>"> <div class="container" style="padding-bottom: 20px" data-aos="fade-up"> <div id="tag-wordcloud" class="card-content"></div> </div> <script type="text/javascript" src="<%- theme.jsDelivr.url %><%- url_for(theme.libs.js.jqcloud) %>"></script> <script type="text/javascript"> <% let tagWordArr = []; site.tags.map(function(tag) { tagWordArr.push({'text': tag.name, 'weight': tag.length, 'link': decodeURI(url_for(tag.path))}); }); let tagWords = JSON.stringify(tagWordArr); %> $('#tag-wordcloud').jQCloud(<%- tagWords %>, { autoResize: true }); </script>
After modification
<link rel="stylesheet" type="text/css" href="<%- theme.jsDelivr.url %><%- url_for(theme.libs.css.jqcloud) %>"> <style type="text/css"> #tag-wordcloud { width: 100%; height: 300px; } </style> <div class="container" data-aos="fade-up"> <div class="card"> <div id="tag-wordcloud" class="card-content"></div> </div> </div> <script type="text/javascript"> $.getScript("<%- theme.jsDelivr.url %><%- url_for(theme.libs.js.jqcloud) %>",function () { <% let tagWordArr = []; site.tags.map(function(tag) { tagWordArr.push({'text': tag.name, 'weight': tag.length, 'link': decodeURI(url_for(tag.path))}); }); let tagWords = JSON.stringify(tagWordArr); %> $('#tag-wordcloud').jQCloud(<%- tagWords %>, { autoResize: true }); }) </script>
Modification content
Overloads the functions that are not overloaded by using the getScript method of Jquery
$.getScript("File reference path",function(){ //overloaded function })
Take the example of valine
Open valine ejs
Original master code
<script src="<%- theme.jsDelivr.url %><%- url_for('/libs/valine/av-min.js') %>"></script> <script src="<%- theme.jsDelivr.url %><%- url_for(theme.libs.js.valine) %>"></script> <script> let metaPlaceholder = <%- JSON.stringify(theme.valine.metaPlaceholder) %> ; //There's a new line here new Valine({ el: '#vcomments', appId: '<%- theme.valine.appId %>', appKey: '<%- theme.valine.appKey %>', notify: '<%- theme.valine.notify %>' === 'true', verify: '<%- theme.valine.verify %>' === 'true', visitor: '<%- theme.valine.visitor %>' === 'true', avatar: '<%- theme.valine.avatar %>', pageSize: '<%- theme.valine.pageSize %>', lang: '<% if (config.language == "zh-CN") { %>zh-cn<% } else { %>en<% } %>', placeholder: '<%= theme.valine.placeholder %>' }); </script>
Modified code
<script> $.getScript("<%- theme.jsDelivr.url %><%- url_for('/libs/valine/av-min.js') %>", function () { $.getScript("<%- theme.jsDelivr.url %><%- url_for(theme.libs.js.valine) %>", function () { new Valine({ el: '#vcomments', appId: '<%- theme.valine.appId %>', appKey: '<%- theme.valine.appKey %>', notify: '<%- theme.valine.notify %>' === 'true', verify: '<%- theme.valine.verify %>' === 'true', visitor: '<%- theme.valine.visitor %>' === 'true', avatar: '<%- theme.valine.avatar %>', pageSize: '<%- theme.valine.pageSize %>', lang: '<% if (config.language == "zh-CN") { %>zh-cn<% } else { %>en<% } %>', placeholder: '<%= theme.valine.placeholder %>' }); }) }) </script>
recommend
Page switching loading animation
In pjax Add the following code to the script tag of EJS
// Clear time var timer = null; // Execution progress bar function ProgressStart(){ // Set initial progress var progress = 10; // Create progress bar and css Style var div = document.createElement('div'); div.className = "pjax_progress"; document.body.prepend(div); // Define the maximum and minimum values of random numbers var max=10,mini=3; var result=max-mini; // eliminate clearInterval(timer); // Cumulative progress in 0.5 seconds timer = setInterval(function(){ // random number var num = parseInt(Math.random()*result); var randomResult = num+mini; // accumulation progress+=randomResult $queryAll(".pjax_progress")[0].style.width = progress+"%"; // Stop when progress reaches 95% if(progress>95)progress=95 },500) } // Loading progress bar loading completed function ProgressFinish(){ clearInterval(timer); // After the page is loaded, the progress is 100% and deleted after 0.7 seconds var progress = $queryAll(".pjax_progress"); progress[0].style.width = "100%"; timer = setTimeout(function () { progress[0].parentNode.removeChild(progress[0]) }, 700); } // Function to start PJAX execution document.addEventListener('pjax:send', function () { // Execution progress bar ProgressStart() }); // The functions executed after PJAX is completed can be put together with the above overloads document.addEventListener('pjax:complete', function () { // Loading progress bar loading completed ProgressFinish() });
In my Add the following style code to CSS
.pjax_progress{ position: fixed; top: 0; left: 0; width: 10%; height: 2px; z-index: 103; background: linear-gradient(130deg, #ff0, red); transition: width .4s ease 0s; }
Page switching loading progress bar
In pjax Add the following code to the script tag of EJS
// Function to start PJAX execution document.addEventListener('pjax:send', function () { $("#loading").css("display","flex") }); // The functions executed after PJAX is completed can be put together with the above overloads document.addEventListener('pjax:complete', function () { $("#loading").css("display","none") });
In my Add the following style code to CSS
#loading { position: fixed; top: 0; left: 0; min-height: 100vh; width: 100vw; z-index: 9999; display: none; flex-direction: column; justify-content: center; align-items: center; text-align: center; } #loading .loader { width: 20em; height: 20em; font-size: 10px; position: relative; display: flex; align-items: center; justify-content: center; } #loading .loader .face { position: absolute; border-radius: 50%; border-style: solid; animation: CW 3s linear infinite; } #loading .loader .face:nth-child(1) { width: 100%; height: 100%; color: #ffd700; border-color: currentColor transparent transparent currentColor; border-width: 0.2em 0.2em 0 0; --deg: -45deg; animation-direction: normal; } #loading .loader .face:nth-child(2) { width: 70%; height: 70%; color: #0f0; border-color: currentColor currentColor transparent transparent; border-width: 0.2em 0 0 0.2em; --deg: -135deg; animation-direction: reverse; } #loading .loader .face .circle { position: absolute; width: 50%; height: 0.1em; top: 50%; left: 50%; background-color: transparent; transform: rotate(var(--deg)); transform-origin: left; } #loading .loader .face .circle::before { position: absolute; top: -0.5em; right: -0.5em; content: ''; width: 1em; height: 1em; background-color: currentColor; border-radius: 50%; box-shadow: 0 0 2em, 0 0 4em, 0 0 6em, 0 0 8em, 0 0 10em, 0 0 0 0.5em rgba(255,255,0,0.1); }
Hexo related articles https://www.islu.cn/categories/Hexo/