阅读 6605

十五分钟--分页逻辑--包学包会

分页组件的构成

废话不多说,我们先来分析一下一个分页组件的结构,实际这个分析很关键,比真正的逻辑判断重要的多,下面先看图:

我们可以看到此分页组件:

《上一页》《下一页》 2 个 : 2
《首页》《尾页》 2 个 : 2
 省略号 2 个 : 2
 当前页 1 个 : 1
 当前页左右各2个 :2 * 2
复制代码

所以这个分页组件一共是由 2 + 2 + 2 + 1 + 2 * 2 = 11 个 元素构成。记住这个数,给这个变量起名字叫baseCount,待会要着重用它。分析到这逻辑实际已经完成74%了,是不是惊呆了?但是不要着急,我们继续分析一下分页组件需要哪些参数:

参数我已经标注好了,大家应该能知道这几个参数的意思,我就不解释了。好,说回刚才的那个baseCount,我们看看baseCount和组件变量有啥关系,发现只跟around有关系:baseCount = 2 + 2 + 2 + 1 + 2 * around。到这完成75%。

怎么使用baseCount

我们已经得到一个很简单的值:baseCount,但是它有什么用呢?实际上它很关键,我们能够用这个值来判断分页组件什么时候出现省略号。比如上面图中这个组件,除掉两边的上一页、下一页两个按钮,中间部分一共有11 - 2 = 9个元素,也就是说当分页的总数total <= 9(baseCount - 2)的时候,是不需要省略号的,因为位置够用,都能显示完全。

进度达到了80%,go on,那什么时候出现省略号呢?嗯,这是个好问题,不过我们在确定啥时候出现省略号之前最好先弄清楚省略号有啥作用,这是本篇文章第二个关键点,也是最重要的一个关键点。

省略号的作用

先来看个小问题:1,...,3,4,5。这其中的省略号代表着啥?代表2吧。可是省略号这里直接用2不就行了吗,本身2也就占一个位置,用省略号岂不是多此一举。所以省略号的正确用法应该如这样:1,...,4,5,6。这里省略号代表2,3。因此省略号的作用就是最少代替2个元素(实际很多分页组件实现过程中省略号只代替了一个元素,也挺好的)。

接下来看分页组件省略号出现的位置,一般会有三种情况,上面的例子是一种,就是两边都出现省略号,还有两种如下:

1、只出现在后面

2、只出现在前面

出现省略号的前提条件是total > baseCount -2,因为可用位置不够显示完全所有页数。

a.只出现在后面的情况,首先确定什么时候前面刚好出现省略号?根据刚刚得出的省略号的作用,也就是说它最少代替两个元素。所以我们就取这个最小值2,此时是在前面刚刚出现省略号,省略号代表的越多则说明cur越往后。

这个时候cur的位置应该是在:首页(1) + 省略号最小值(2[如果采用省略号只最少只代替一个元素的方案,这里是1]) + cur左边的值around(2)的下一个,即cur = 1 + 2 + around + 1,标记一下叫startPosition。因此当cur < startPosition时前面是不会出现省略号的,仅在后面出现省略号,所以就确定了省略号开始出现时的位置:startPosition = 1 + 2 + around + 1。

b.同样的逻辑,我们还可以得出只在前面出现,后面不会出现省略号的一个临界位置:endPosition = 尾页(total) - 省略号最小值(2[如果采用省略号只最少只代替一个元素的方案,这里是1]) - cur 右边的值(2) - 1。即cur > endPosition时只在前面出现省略号。

ok,逻辑分析已经完成了95%,还剩下一种两边都出现省略号的情况,我们不用分析了,除去刚才的两种情况就是它了,也就是当 startPosition <= cur && cur <= endPosition。

其他的位置怎么显示

分析完省略号的位置,其他的就超级简单了,还记得刚才那个很重要的baseCount吗,还是用它。 刚才得到的baseCount是11,因为上一页和下一页一直都会存在。我们可以先不用管这俩,只看中间实际用到的9个位置。

我们可以看到当省略号只出现在后面时,可用位置的最后两个一定是 ... 和 total。所以这个省略号前面的还剩下9 - 2 = 7个,给这个变量也取个名字叫surplus,就从1开始显示到surplus就好了。也是同样的道理,当省略号只出现在前面时,前面的两个位置一定是 1 和 ...。所以后面就是从 (total-surplus) 一直到 total 了。

还有就是两边都出现省略号,前面两个肯定是 1 和 ...,后面两个又肯定是 ... 和 total。那么中间的就是cur以及其左右两边的相邻的around个。

当有省略号出现时,这种逻辑保证了分页组件总共需要的元素的个数是固定的,且只跟around有关,around取值建议为2或者3。到此,分页逻辑分析就全部结束了,下面是一个生成分页组件对应数组的方法,供各位小伙伴参考:

/**
 * 
 * @param {Number} total 
 * @param {Number} cur 
 * @param {Numbre} around 
 */
const makePage = (total,cur,around) => {
    let result = [];
    let baseCount = around * 2 + 1 + 2 + 2 + 2; //总共元素个数
    let surplus = baseCount - 4; //只出现一个省略号 剩余元素个数
    let startPosition = 1 + 2 + around + 1;//前面出现省略号的临界点
    let endPosition = total - 2 - around - 1;//后面出现省略号的临界点

    if(total <= baseCount - 2){ //全部显示 不出现省略号
        result =  Array.from({length: total}, (v, i) => i + 1);
    }else{ //需要出现省略号
        if(cur < startPosition){ //1.只有后面出现省略号
            result = [...Array.from({length: surplus}, (v, i) => i + 1),"...",total]
        }else if(cur > endPosition) { //2.只有前边出现省略号
            result = [1,'...',...Array.from({length: surplus}, (v, i) => total - surplus + i + 1)]
        }else{ //3.两边都有省略号
            result = [1,'...',...Array.from({length: around * 2 + 1}, (v, i) => cur - around + i),'...',total]
        }
    }

    return result
}
makePage(8,2,2);//[1, 2, 3, 4, 5, 6, 7, 8]
makePage(20,3,2);//[1, 2, 3, 4, 5, 6, 7, "...", 20]
makePage(20,10,2);//[1, "...", 8, 9, 10, 11, 12, "...", 20]
makePage(20,19,2);//[1, "...", 14, 15, 16, 17, 18, 19, 20]
复制代码

总结

听说用自己写的分页组件,ajax速度会比以前快3毫秒,所以学会了后赶紧自己也封装一个分页组件试一试吧,用react、vue或者源生js都可以,逻辑都是一样的,还可以根据需求加上跳转到第几页、是否显示首页尾页等相关功能和逻辑。

关注下面的标签,发现更多相似文章
评论

查看更多 >