Pjax使用实例


张登友,张登友的博客,张登友的网站——

使用pjax无刷新加载网页,实现切换页面音乐不间断播放

Pjax 原理

首先要知道 Pjax = Ajax + pushState。当用户进行超链请求时,Pjax 会拦截请求,然后触发 Ajax 请求和 pushState。其中,Ajax 使你的页面局部刷新,pushState 用于修改 URL 而不跳转页面,从而实现不跳转页面局部刷新的功能。

官方文档解释

  • 它监听您想要的每个链接点击(默认情况下都是)。
  • 单击内部链接时,Pjax通过AJAX获取页面的HTML。
  • Pjax渲染页面的DOM树(不加载任何资源-图像、CSS、JS等)。
  • 它检查是否可以更换所有定义的部件:
    • 如果页面不符合要求,则使用标准导航。
    • 如果页面满足要求,Pjax将进行所有定义的DOM替换。
  • pushState 用于修改 URL 而不跳转页面

安装pjax

Pjax 有依赖和不依赖 jQuery 的两种版本:

引用文件

我这里使用npm安装(二选一安装即可)

npm install pjax # 原生命令安装
cnpm install pjax # 淘宝加速镜像安装

然后在页面引入

<script src="./node_modules/pjax/pjax.js"></script>

或者直接使用 JSDelivr 公共的 CDN 地址(推荐)

<script src="https://cdn.jsdelivr.net/npm/pjax/pjax.js"></script>

创建实例化对象

实例化Pjax并将选项作为对象传递给构造函数:

let pjax = new Pjax({
    selectors: ["head title", ".aa", ".pp"],//填写要改变的部分,标签直接写标签名,id选择器需要加#,类名需要加.
    history: true, //是否添加近浏览器历史记录
    pushState: true,//是否启用 pushState。禁用后 Pjax 就变成了 Ajax。
    scrollRestoration: true,//切换页面后,Pjax 将尝试恢复滚动位置。
    cacheBust: false //是否在 URL 上添加时间戳,防止浏览器缓存。
});

重载pjax

因为pjax本身也会被自己拦截而不进行刷新,这会导致在第二个页面无法执行,并且使网页全部刷新,这时候我们需要在pajx执行完成之后重新再创建一次pjax构造对象(其他需要重新加载的函数同理,比如valine和waline评论模块)

function pjax_reload() {
  //其他需要重新加载的函数也可以添加在这里
    let pjax = new Pjax({
        selectors: ["head title", ".aa", ".pp"],
        history: true,
        pushState: true,
        scrollRestoration: true,
        cacheBust: false
    });
}

// Pjax 完成后,重新加载上面的函数
document.addEventListener("pjax:complete", function () {
    pjax_reload();
});

加载音乐播放器

<div id="player"></div> <!-- 音乐播放器的容器 -->
<script src="js/APlayer.min.js"></script> <!-- 引入aplayer播放器的js文件 -->

<!-- 实例化音乐播放器 -->
<script>

    function music(data) {
        let ap = new APlayer({
            container: document.getElementById('player'),
            fixed: true,
            autoplay: false,
            theme: '#FADFA3',
            loop: 'all',
            order: 'random',
            preload: 'auto',
            volume: 0.7,
            listFolded: false,
            listMaxHeight: 90,
            lrcType: 3,
            audio: [{
                "name": "侧脸",
                "artist": "于果",
                "url": "./music/侧脸-于果.flac",
                "cover": "./cover/1.png",
                "lrc": "./music/aa.lrc"
            }, {
                "name": "哈哈哈",
                "artist": "测试",
                "url": "./music/侧脸-于果.flac",
                "cover": "./cover/1.png",
                "lrc": "./music/aa.lrc"
            }]

        });
    }
    music();
</script>

完整代码

最后贴出代码,若想测试的话,可以复制两份出来,将超链接改一下即可

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <meta charset="UTF-8">
    <title>主页</title>
    <link rel="stylesheet" href="node_modules/aplayer/dist/APlayer.min.css">
    <script src="./node_modules/pjax/pjax.js"></script>
</head>

<body>
    <a class="aa" href="index2.html">测试网页1</a>
    <p class="pp">测试文本</p>
    <div id="player"></div>
    <p class="pp">哈哈哈哈哈</p>
    <script>
        let pjax = new Pjax({
            selectors: ["head title", ".aa", ".pp"],
            history: true,
            pushState: true,
            scrollRestoration: true,
            cacheBust: false
        });

        function pjax_reload() {
            let pjax = new Pjax({
                // 这里由于加载pjax,函数本身也用了无刷新,再加载第二个网页时会报错,需要进行重载
                selectors: ["head title", ".aa", ".pp"],
                history: true,
                pushState: true,
                scrollRestoration: true,
                cacheBust: false
            });
        }

        // Pjax 完成后,重新加载上面的函数
        document.addEventListener("pjax:complete", function () {
            pjax_reload();
        });
    </script>

    <script src="js/APlayer.min.js"></script>
    <script>
      //aplayer音乐播放器
        function music() {
            let ap = new APlayer({
                container: document.getElementById('player'),
                fixed: true,
                autoplay: false,
                theme: '#FADFA3',
                loop: 'all',
                order: 'random',
                preload: 'auto',
                volume: 0.7,
                listFolded: false,
                listMaxHeight: 90,
                lrcType: 3,
                audio: 
              	// 模拟请求到的数据
              	[{
                    "name": "侧脸",
                    "artist": "于果",
                    "url": "./music/侧脸-于果.flac",
                    "cover": "./cover/1.png",
                    "lrc": "./music/aa.lrc"
                }, {
                    "name": "哈哈哈",
                    "artist": "测试",
                    "url": "./music/侧脸-于果.flac",
                    "cover": "./cover/1.png",
                    "lrc": "./music/aa.lrc"
                }]

            });
        }
        music();
    </script>
</body>

</html>

使用效果

在我们重新加载网页之后,音乐没有被打断并且继续播放,开发工具里也是显示只替换了我们的在选择器里选择的title,p,和a

我的博客过段时间也会将这个功能合并进入(主要调试太费时间了,会出现很多bug,暂时不上线)

pjax

参考文章:https://liuyib.github.io/2019/09/24/use-pjax-to-your-site/


文章作者: 张登友
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 张登友 !
  目录