Adding Pjax to the matrix theme

How to add Pjax to a matery theme

Pjax benefits

  1. 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.
  2. 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

  1. Comment page EJS (I use valine, so I need to modify the valine.ejs page)
  2. Google statistics page (Google Analytics. EJS)
  3. Article directory (post-detail-toc.ejs)
  4. Talk about the page (arttalk. EJS)
  5. Tag wordcloud (tag wordcloud. EJS)
  6. categories radar chart (category radar. EJS)
  7. Statistics of Archives (post-calendar.ejs)
  8. 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/

Added by kelesis on Tue, 25 Jan 2022 08:32:32 +0200