前言

前段时间在主题添加jQuery.Pjax库,遇到问题太大不得不放弃,可能局限性太大。而且容器不能支持多种方。早上在Github搜索看到MoOx/pjax看起来效果不错,集成主题果然很赞。

简介

Easily enable fast Ajax navigation on any website (using pushState + xhr)

Pjax是一个独立的JavaScript模块,它使用AJAX(XmlHttpRequest)pushState()来提供快速浏览体验。

它可以彻底改变标准网站(服务器端生成或静态网站)的用户体验,特別是宽带链接低俗的用户。

Pjax does not rely on other libraries, like jQuery or similar. It is written entirely in vanilla JS.

该库不依赖任何库文件,纯粹是原生JavaScript编写。

Github:https://github.com/MoOx/pjax

那么作者对此评价:

  • 不仅限于一个容器
  • 完全支持浏览器历史(后退和前进)
  • 支持键盘浏览
  • 自动退回到外部页面的标准导航
  • 自动回退到没有适当DOM树的内部页面的标准导航
  • 轻松地添加非常酷的CSS转换(动画)
  • 大约4kb(缩小和缩小)

更多的内容可以去文档查看。

实例

文档有个简单的例子,假如你的页面DOM结构如下:

<!DOCTYPE html>
<html>
<head>
  <!-- metas, title, styles, ... -->
</head>
<body>
  <header class="my-Header"><nav><!-- a .is-active is in there --></nav></header>
  <section class="my-Content">
    Sha blah <a href="/blah ">blah</a>.
  </section>
  <aside class="my-Sidebar">Sidebar stuff</aside>
  <footer class="my-Footer"></footer>
  <script src="onDomReadystuff.js"></script>
  <script><!-- analytics --></script>
</body>
</html>

那么你需要引入该js文件:

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

并且声明初始化:

var pjax = new Pjax({ selectors: ["title", ".my-Header", ".my-Content", ".my-Sidebar"] })

selectors选择网站DOM需要加载的地方。里面有个title是网页的标题变换。

就这样完成基本需求了。

所以对jquery.pjax区别在于:

  • 没有jQuery依赖
  • 不限于一个容器
  • 没有服务器端要求
  • 适用于CommonJS环境(Webpack / Browserify),AMD(RequireJS)甚至全局
  • 允许使用CSS动画进行页面转换
  • 可维护性

Pjax仅适用于支持history.pushState()API的浏览器。

当API不支持时,就算引入该库也不会发生什么。

要查看浏览器是否确实支持Pjax,请使用Pjax.isSupported()

使用

根据上面实例最基本的声明是:

new Pjax()

当你实例化Pjax时候,可以将选项作为对象传递给构造函数:

var pjax = new Pjax({
  elements: "a", // 默认"a[href], form[action]"
  selectors: ["title", ".my-Header", ".my-Content", ".my-Sidebar"]
})

在网页的".my-Header", ".my-Content", ".my-Sidebar"选择器中所有a标签超链接启用pjax加载。

但如果你想在特定的a标签超链接进行pjax加载的话,有俩个方法:

  • 使用自定义选择器,如a.js-Pjax 或者 .js-Pjax a
    例如:
    javascript
    var pjax = new Pjax({ elements: "a.js-Pjax" })
  • 重写Pjax.prototype.getElements里面querySelectorAllelements选项,该函数返回一个NodeList对象
    javascript
    Pjax.prototype.getElements = function() {
    return document.getElementsByClassName(".js-Pjax")
    }
    var pjax = new Pjax()

loadUrl(href, [options])

使用这种方法,手动触发加载URL:

var pjax = new Pjax()

pjax.loadUrl("/your-url")

pjax.loadUrl("/your-other-url", {timeout: 10})

handleResponse(responseText, request, href)

此方法采用JavaScript原生响应,处理URL然后调用pjax.loadContent()将其加载到DOM中:

var pjax = new Pjax();

pjax._handleResponse = pjax.handleResponse;

pjax.handleResponse = function(responseText, request, href) {
  if (request.responseText.match("<html")) {
    pjax._handleResponse(responseText, request, href);
  } else {
    // 处理响应
  }
}
  • responseText (string): 原始的响应内容,相当于request.responseText
  • request (XMLHttpRequest): XHR对象
  • href (string): URL传递给loadUrl()

refresh([el])

使用此方法将Pjax绑定到初始化Pjax时不存在的DOM元素的子元素。

例如:由另一个库或脚本动态插入的内容。如果不带参数调用,Pjax将再次解析整个文档以查找新插入的元素。

//插入新DOM内容后运行callback或Promise
var newContent = document.querySelector(".new-content");
pjax.refresh(newContent);

reload()

强制页面重载,和window.location.reload()无异。


选项

elements (String, default: “a[href], form[action]”)

selectors (Array, default: [“title”, “.js-Pjax”])

switches (Object, default: {})

Objects containing callbacks that can be used to switch old elements with new elements. Keys should be one of the defined selectors.

Examples:

var pjax = new Pjax({
  selectors: ["title", ".Navbar", ".js-Pjax"],
  switches: {
    // "title": Pjax.switches.outerHTML // default behavior
    ".Navbar": function(oldEl, newEl, options) {
      // here it's a stupid example since it's the default behavior too
      oldEl.outerHTML = newEl.outerHTML
      this.onSwitch()
    },

    ".js-Pjax": Pjax.switches.sideBySide
  }
})

Callbacks are bound to Pjax instance itself to allow you to reuse it (ex: this.onSwitch())

更多信息阅读:文档

history (Boolean, default: true)

启用使用pushState()。禁用此功能将阻止Pjax更新浏览器历史记录。

analytics (Function | Boolean, default: a function that pushes _gaq _trackPageview or sends ga pageview

谷歌统计重载

cacheBust (Boolean, default: true)
设置为true时,将时间戳查询字符串段附加到请求的URL来禁止浏览器缓存。

debug (Boolean, default: false)
调试模式。

timeout (Integer, default: 0)
XHR请求的超时时间(以毫秒为单位),设置为0禁用。

事件

  • pjax:send: 在Pjax请求开始后触发
  • pjax:complete: 在Pjax请求完成后触发
  • pjax:success: 在Pjax请求成功后触发
  • pjax:error: Pjax请求失败后触发。请求对象将作为一起传递给event.options.request

常见就像页面过渡动画的效果:

document.addEventListener('pjax:send', topbar.show)
document.addEventListener('pjax:complete', topbar.hide)

在WordPress主题使用

其实在WordPress主题中使用并不是太难,主要把设置选项摸索清楚就行了,下面是我的主题配置选项,打开F12查看对应的DOM相信也会明白:

//参数配置
            var pjax = new Pjax({
                elements: 'a[href]:not([href^="#"])', // default is "a[href], form[action]"
                cacheBust: false,
                debug: false,
                selectors: [
                    'title',
                    '#header',
                    '#material-main'
                ]
            });

            //在Pjax请求开始后触发
            document.addEventListener('pjax:send', function () {
                $('body').append('<div id="material-loading-cover" class="material-loading-dom animated slideInDown"><svg id="material-loading" class="spinner" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg"><circle class="path" fill="none" stroke-width="6" stroke-linecap="round" cx="33" cy="33" r="30"></circle></svg></div>');
            });

            //在Pjax请求完成后触发
            document.addEventListener('pjax:complete', function () {
                $('body').attr('class',$('#material-main').data('class'));

                //重载函数
                ...

                if (typeof _hmt !== 'undefined') {
                    // support 百度统计
                    _hmt.push(['_trackPageview', location.pathname + location.search]);
                }
                if (typeof ga !== 'undefined') {
                    // support google analytics
                    ga('send', 'pageview', location.pathname + location.search);
                }
                if (typeof Prism !== 'undefined') {
                    //Prism.highlightAll(true,null);
                    self.Prism.highlightAll(event);
                }

                $('#material-loading-cover').remove();
            });

            //在Pjax请求成功后触发
            document.addEventListener('pjax:success', function() {

            });

            //Pjax请求失败后触发,请求对象将作为一起传递event.options.request
            document.addEventListener('pjax:error', function() {
                bar('系统出现问题,请手动刷新一次','3000');
            });
            //搜索事件处理
            $(document).on('submit', '.form-group', function (e) {
                e.preventDefault(); // 去除搜索框默认事件
                var site = document.location.origin,
                    val = $('.top-nav-search').val(),
                    search = site + '/?s=' + val;
                pjax.loadUrl(search);
            });``

本博客所有内容采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可

转载文章请注明:MoOx Pjax使用笔记 - https://iiong.com/moox-pjax-use-notes.html

分类: 编程技术

淮城一只猫

永远年轻,永远热泪盈眶

发表评论

电子邮件地址不会被公开。 必填项已用*标注

我不是机器人*

EA PLAYER &

历史记录 [ 注意:部分数据仅限于当前浏览器 ]清空

      00:00/00:00