之前看大家都增加了页码跳转功能,觉得很实用,就抄了过来,顺带把页码的样式整个优化了一下。以前的页码样式一直是 Butterfly 默认的,当时文章少,页码就一个,所以也没觉得不适,但如果后面页数多了,肯定会导致手机端显示错位的问题。就像这样:

所以重新设计一个页码样式是很有必要的。
首先看一下别人的优秀设计。第一个是 @张洪 的博客,洪哥不愧是设计大佬,交互动画和细节处理都是我友链的博客里做的最好的。下图为电脑端的页码样式,该有的功能基本上都有,“上一页”、“下一页”和页码跳转这三个按钮单独设计了优美的交互动画。页码跳转基本结构是一个输入框加一个确认按钮,洪哥将确认按钮覆盖在输入框上方,巧妙的将它们整合成了一个模块,只有当光标移动到模块上方时,输入框才会展开,这样设计既美观又节省了空间。另外,页码跳转功能的逻辑设计考虑的很周全,只支持输入有效范围内的整数,对于超出范围的数会强制转换为最大值,而对于自然数以外的其它字符,则无法输入。输入完页码后,可以通过确认按钮完成跳转,也可以通过回车键完成跳转。

至于手机端的适配,洪哥选择的方案是舍去低频的部件,只保留高频的“上一页”和“下一页”按钮,避免了手机端显示过于臃肿的现象,使得整体效果更加美观。

第二个是 @轻笑 的博客,他的手机端和电脑端样式基本一样,都支持页码跳转,因为取消了“上一页”和“下一页”按钮,且缩小了按钮尺寸,所以也不会出现错位的现象,不失为一种好方案。在页码跳转的逻辑功能方面,只支持通过点击跳转按钮完成跳转,不支持回车键跳转,另外对于超出有效范围的页码也没有进行强制转换(实际逻辑上是强制跳转到最后一页,只是前端显示没有做限制)。

最后看的是 @Leonus 的博客,他的整体样式跟洪哥差不多,逻辑功能也一样,但砍掉了“上一页”、“下一页”和页码跳转三个按钮的交互动画,砍掉了页码跳转的确认按钮,只保留了回车键跳转,这样整体看起来简洁很多,也更契合他的主题。移动端的适配也是采取的跟洪哥一样的方案,只保留“上一页”和“下一页”按钮。

综合考虑下来决定采用 Leonus 的方案,毕竟我的博客主题也是跟他的更契合。

电脑端的样式跟 Leonus 的一样,但手机端我还是希望保留页码跳转等功能,所以我在 Leonus 结构的基础上稍微做了下调整,在仅增加一个按钮的情况下,使其既保留了页码跳转的功能,又保留了当前页码显示功能。另外,不仅主页文章列表,分类页、标签页和归档页等页面也做了同样的适配。

首先通过order属性将页码输入框移至中间显示,然后通过 js 读取当前页码使其通过页码输入框的placeholder显示出来,这样,就使其同时具备了页码显示和页码跳转的功能。
代码实现
首先 pagination.pug 部分,将页面跳转模块应用到全部,大概在第32行的位置。
1 2 3 4 5 6 7 8
   | else   nav#pagination     .pagination       if is_home()         - options.format = 'page/%d/#content-inner'         //- 如果是一图流,可以把#content-inner删了       !=paginator(options)       input.toPageInput(placeholder="Go" oninput="value=value.replace(/[^0-9]/g,'')" maxlength="3")
   | 
 
在逻辑代码部分,由于洪哥他们仅支持主页文章列表的页码跳转,并没有对分类页、标签页和归档页的页码做适配,所以这里对原 js 代码做了改进。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
   | var ctrl = {     toPageJump() {         let e = document.querySelector("#pagination input.toPageInput");         function k(v) {             var p = window.location.pathname,                  i = [],                 c = -1;             while ((c = p.indexOf('/', c + 1)) !== -1) i.push(c)              var l = i.length             if (l == 1 || p.substring(1, i[l-2]) == "page") return ["/#content-inner", `/page/${v}/#content-inner`]             else if (l >= 4 && p.substring(i[l-3]+1, i[l-2]) == "page") {                 var j = p.substring(0, i[l-3]+1)                 return [`${j}`, `${j}page/${v}/`]             } else return [`${p}`, `${p}page/${v}/`]         }         e && (e.addEventListener("input", () => {             let t = document.querySelectorAll(".page-number")                 , n = t[t.length - 1].innerHTML;             Number(e.value) > n && (e.value = n),                 Number(e.value) < 1 && (e.value = "")         }),             e.addEventListener("keyup", t => {                 "Enter" == t.key && "" != e.value && "0" != e.value && pjax.loadUrl("1" == e.value ? k(e.value)[0] : k(e.value)[1])             })         )     },
      getCurrentPage() {         if (window.innerWidth <= 768 && (document.querySelector("#body-wrap.page.home") || document.getElementById("tag") || document.getElementById("category") || document.getElementById("archive"))) {             var c = document.querySelector(".pagination .page-number.current").innerHTML;             if (c) {                 var t = document.querySelector(".pagination .toPageInput");                 if (t) {                     t.placeholder = "第 " + c + " 页";                 }             }         }     } }
  | 
 
常用的window.location属性:
1 2 3 4 5 6 7 8
   | console.log(window.location.href);       console.log(window.location.protocol);   console.log(window.location.host);       console.log(window.location.hostname);   console.log(window.location.port);       console.log(window.location.pathname);   console.log(window.location.search);     console.log(window.location.hash);      
   |