简单分页导航器自实现

分页导航器

先看看各平台的分页导航器
CSDN:
在这里插入图片描述
Iconfont:
在这里插入图片描述
经分析比对,上述两种都是 通过实时计算页码的展示形态,动态insert DOM。
本质是: 强算法

我自身实现的有点像,但是较低难度。嘿嘿。
直接看效果吧。
在这里插入图片描述
后期会将 “共31页”的31改成input 点击即跳转即可。

动画:
1、 overflow 配合 inline-block transition动画移动即可
2、.active 配置 index和当前pagination相同即可

css代码

 .bar-group {
   float: right;
    max-width: 418px;
    overflow-x: hidden;
    .bar-group-container {
      display: inline-block;
      white-space: nowrap;
      transition: transform 0.3s;
      .bar-item {
        display: inline-block;
        text-align: center;
        color: #333;
        height: 32px;
        width: 32px;
        line-height: 32px;
        margin-right: 6px;
        font-size: 14px;
        border-radius: 99px;
        &:hover {
          cursor: pointer;
          background-color: #ffd6d6;
        }
        &.active {
          color: white;
          background-color: red;
        }
      }
    }
  }

算法逻辑:
需求:保证用户体验感,比如:最大限制11格子,高亮的数字左边必定包含6格,右边包含4格。
在这里插入图片描述
当点击指定页码时,当前索引为基准(index)。以及已经偏移的步长(step)根据6-4规则,绞尽脑汁思考。计算。得出:
比如当前点击数字的索引为 24 ,当前步长 14
shouldMoveStep:当前需要移动的距离 ( 24 - 20 = 4 )
maxMoveStep:理论上最大能移动的距离 ( 24 + 14(step) - 6(左侧格子占位6) ) 得出 32
两者取最小的。
其实maxMoveStep仅在step===0 时才有意义,它的设立是防止数字的过分偏移。
最后,需要step> 0时,需要进行边界限制,Math.max或min 0以及totalPage-maxPage (可以移动的极限步长),防止越边界)

总结:

step === 0 需要判断 shouldMoveStep 和 maxMoveStep
step > 0 需要判断shouldMoveStep 和 边界上下限

核心代码如下:

  /**
   * handlePageNumberClick: 内部逻辑主要计算步长
   * step->calcMove: 
   * step情况有三种:
   * 1.中间移动时:前后相减 得出 相距步长 直接跳 (step > 0)
   * 2.靠起始位置移动:需要计算出当前限制步长 与 相距步长 相较取小(左开始step === 0)
   * 3.靠终点位置移动:需要计算出当前限制步长 与 相距步长 相较取小(右开始step === 0)
   */
  const handlePageNumberClick = (index) => {
    const oldIndex = activePageIndex;
    let shouldMoveStep, limitMoveStep;// 相距步长  限制步长 
    shouldMoveStep = Math.abs(index - oldIndex); // 兼容左右情况
    if (
      index > MIDDLE_PAGE &&
      index > oldIndex
    ) {
      // 朝右:
      // 限制步长:(左侧步长为0时需要限制,保证数字居中)
      limitMoveStep = index - MIDDLE_PAGE;
      if (shouldMoveStep < limitMoveStep) {
        // 注:右移可能越界,若越界则取极值totalPage - MAX_PAGE
        const calcMove = Math.min(totalPage - MAX_PAGE, step + shouldMoveStep);
        setStep(calcMove);
      } else {
        setStep(step + limitMoveStep);
      }
    } else if (
      totalPage - index > MAX_PAGE - MIDDLE_PAGE &&
      index < oldIndex
    ) {
      // 朝左:
      // 限制步长:(右侧步长为0时需要限制,保证数字居中)
      limitMoveStep = totalPage - index - (MAX_PAGE - MIDDLE_PAGE);
      if (shouldMoveStep < limitMoveStep) {
        // 注:左移可能越界,若越界则取极值totalPage - MAX_PAGE
        const calcMove = Math.max(0, step - shouldMoveStep);
        setStep(calcMove);
      } else {
        setStep(step - limitMoveStep);
      }
    }

    // 2、回调
    setNumIndex(index);
    onHandlePaginationClick(index);
  }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值