Skip to content

分页封装

警告

个人封装,可能不是那么完备。

请谨慎选择。

模版页面

html
<hlx-template
  component-type="newsPageTotal"
  component-query-option="{'columnIds':[],'start':0,'page':10000,'count':10,'showMedium':'PC'}"
  component-variable="paginationList"
></hlx-template>

<div id="wanx-hlx-thymeleaf-pagination"></div>
html
<script th:inline="javascript">
  {% if conf.isHlx %}
    var data = [[${paginationList.pageData}]]
    var current = data.current
    var pages = data.pages
    var href = data.href
  {% else %}
    var pages = "10";
    var current = "6";
    var href = ["javascript:void(0)", "/col502905_2.html", "/col502905_3.html", "/col502905_4.html", "/col502905_5.html", "/col502905_6.html", "/col502905_7.html", "/col502905_8.html", "/col502905_9.html", "/col502905_10.html", "/col502905_2.html"];
  {% endif %}

    new HlxWanxPagination({
      hlx: {
        pages: pages,
        current: current,
        href: href,
      },
      txt: {
        toPagePrefix: "跳到",
        toPageSuffix: "页",
        toPageTxt: "确定",
      },
    }).render("#wanx-hlx-thymeleaf-pagination");
</script>

搜索页

currentPage、pageSize、totalSize 都是 华龙芯 API 返回的

html
<div id="wanx-hlx-search-pagination"></div>
ts
function onRenderHlxSearchPagination(
  currentPage: number,
  pageSize: number,
  totalSize: number
) {
  const param = parseSearchParams();

  /**
   * 总页数
   */
  const totalPage = Math.ceil(totalSize / pageSize);

  const getHrefByPage = function (p: number) {
    const base = window.location.origin + window.location.pathname;

    return (
      base +
      "?keyword=" +
      param.keyword +
      "&currentPage=" +
      p +
      "&pageSize=" +
      pageSize
    );
  };

  new HlxWanxPagination({
    search: {
      currentPage: +currentPage,
      totalPage: totalPage,
      pageSize: +pageSize,
    },
    txt: { toPagePrefix: "", toPageSuffix: "" },

    onClickNext: function () {
      window.location.href = getHrefByPage(currentPage + 1);
    },
    onClickPrevious: function () {
      window.location.href = getHrefByPage(currentPage - 1);
    },
    onClickGo: function (page) {
      if (page > totalPage) {
        // @ts-ignore
        layui.layer.alert("页码超出范围");

        // 阻止默认行为
        return;
      }

      window.location.href = getHrefByPage(page);
    },
    onClickPage: function (page) {
      window.location.href = getHrefByPage(page);
    },
  }).render("#wanx-hlx-search-pagination");
}

HlxWanxPagination 处理结果

最终会生成这样的 html 格式

html
<div id="wanx-hlx-thymeleaf-pagination">
  <a class="previous-page">上一页</a>

  <div class="page-container">
    <a class="page" href="/col502905_2.html">1</a>
    <span class="page-before-dots">...</span>
    <a class="page" href="/col502905_5.html">4</a>
    <a class="page" href="/col502905_6.html">5</a>
    <a class="page active">6</a>
    <a class="page" href="/col502905_8.html">7</a>
    <a class="page" href="/col502905_9.html">8</a>
    <span class="page-after-dots">...</span>
    <a class="page" href="">10</a>
  </div>

  <a class="next-page">下一页</a>

  <div class="jump-container">
    <span class="jump-page-prefix"></span>
    <input class="jump-page-input" />
    <span class="jump-page-suffix"></span>
    <button class="jump-page-button">转到</button>
  </div>
</div>

其中当前页(page) 会添加 active 样式

警告

HlxWanxPagination 只会生成 dom ,并不会生成 css!

css 需要自己编写

参考代码

警告

仅供参考。

经过几个版本的验证,相对稳定,但不排除 bug 修复后未能更新的情况

scss
#wanx-hlx-search-pagination,
#wanx-hlx-thymeleaf-pagination {
  margin-top: 24px;

  display: -ms-flexbox;
  display: flex;

  -ms-flex-align: center;
  align-items: center;

  -ms-flex-pack: center;
  justify-content: center;

  -ms-flex-wrap: wrap;
  flex-wrap: wrap;

  //   跳到 xxx 页
  .jump-container {
    font-family: PingFangSC, helvetica neue, arial, microsoft yahei ui,
      microsoft yahei;

    font-size: 16px;
    color: #000;

    .jump-page-prefix {
      margin-left: 4px;
    }

    .jump-page-input {
      width: 50px;
      height: 30px;
      border: 1px solid #ccc;
      margin: 0 4px;

      padding: 0 4px;
    }

    .jump-page-suffix {
      margin-right: 4px;
    }

    .jump-page-button {
      width: 50px;
      height: 30px;
      text-align: center;
      border: none;
      border-radius: 5px;
      cursor: pointer;
      background: #ddd;
    }
  }

  // 上下一页
  .previous-page,
  .next-page {
    color: #666;
    background: #fff;
    border-color: #ddd;
    border-width: 1px;
    border-style: solid;
    border-radius: 3px;
    height: 30px;
    line-height: 30px;
    text-align: center;
    width: 67px;

    margin-right: 10px;

    cursor: pointer;

    &:hover {
      background: #eee;
      border-color: #ccc;
    }
  }

  .page-container {
    display: flex;
    display: -ms-flexbox;

    .page {
      display: block;
      width: 30px;
      height: 30px;
      line-height: 30px;
      text-align: center;
      background: #fff;
      border-color: #ddd;
      border-width: 1px;
      border-style: solid;
      color: #666;

      margin-right: 10px;
    }

    .page.active {
      background: #eee;
      border-color: #ccc;
    }

    .page:hover {
      background: #eee;
      border-color: #ccc;
    }

    .page-before-dots,
    .page-after-dots {
      width: 30px;
      height: 30px;
      line-height: 30px;
      text-align: center;
      background: #eee;
      border-color: #ccc;
      border-width: 1px;
      border-style: solid;
      color: #666;
      margin-right: 10px;
    }
  }
}

@media screen and (max-width: 768px) {
  #wanx-hlx-thymeleaf-pagination {
    .page-container {
      display: none;
    }

    .jump-container {
      display: none;
    }
  }
}
ts
const DEFAULT_SHOW_PAGE_NUM = 5;

/**
 * hlx 分页配置
 */
interface IHlxConfig {
  current: string | number; // 当前页,通过 hlx 注入数据
  pages: string | number; // 总页数,通过 hlx 注入数据
  href: string[]; // 分页链接,通过 hlx 注入数据
}

interface ISeachConfig {
  currentPage: number | string;
  pageSize: number | string;
  totalPage: number | string;
}

/**
 * 分页存在多种情况,以5页为例:
 * - 当前页为1,则显示1,2,3,4,5 ... 10
 * - 当分页在中间时,则显示 1 ... 3,4,5,6,7 ... 10
 * - 当前页为10,则显示 1 ... 6,7,8,9,10
 *
 * startPage 与 endPage 就是控制 中间循环多少个 DOM 的配置
 */
interface IControlPage {
  startPage: number;
  endPage: number;
}

type IBeforeFunc = (currentPage: number, totalPage: number) => IControlPage;

type IAfterFunc = (
  hlxData: {
    currentPage: number;
    totalPage: number;
    hrefList: string[];
    showPageNum: number;
  },
  doms: ICreatedPaginationDom & {
    pageContainer: HTMLElement;
    jumpContainer: HTMLElement;
  }
) => void;

type IOnGoPage = (
  page: number,
  hlxData: { currentPage: number; totalPage: number; hrefList: string[] }
) => void;

interface PaginationOptions {
  /**
   * hlx 平台提供的数据,通过 hlx模版 注入
   */
  hlx?: IHlxConfig;

  search?: ISeachConfig;

  /**
   * 各种文字配置,如 上一页,下一页,跳转
   */
  txt?: ITxtConf;

  conf?: {
    /**
     * ... 中间显示多少个page ...
     *
     * 如:5
     */
    defaultShowPageNum?: number;
  };

  /**
   * 创建 dom 前
   */
  onBefore?: IBeforeFunc;

  /**
   * 创建 dom 后
   */
  onAfter?: IAfterFunc;

  /**
   * 点击跳转页
   */
  onClickGo?: (page: number) => void;

  /**
   * 点击下一页
   */
  onClickNext?: () => void;

  /**
   * 点击上一页
   */
  onClickPrevious?: () => void;

  /**
   * 点击页码
   */
  onClickPage?: (page: number) => void;
}

// ------------------------------------------------------------------------------------------------------------------------

class HlxWanxPagination {
  private options: PaginationOptions;
  constructor(options: PaginationOptions) {
    this.options = options;
  }

  render(selectors: string) {
    const renderDom = document.querySelector(selectors);
    if (!renderDom) {
      return console.error("缺少渲染元素!");
    }

    // todo 分路
    if (this?.options?.hlx) {
      this.renderByHlx(renderDom);
    } else if (this?.options?.search) {
      this.renderBySearch(renderDom);
    }
  }

  // ------------------------------------------------------------------------------------------------------------------------
  // 搜索 页面使用的分页

  private renderBySearch(renderDom: Element) {
    const options = this.options;
    const { txt = {}, search = {}, conf = {} } = options;
    const {
      currentPage: _currentPage,
      pageSize: _pageSize,
      totalPage: _totalPage,
    } = search as ISeachConfig;

    const showPageNum = conf.defaultShowPageNum || DEFAULT_SHOW_PAGE_NUM;

    const currentPage = +_currentPage;
    const pageSize = +_pageSize;
    const totalPage = +_totalPage;

    const beforeFunc =
      options.onBefore ||
      HlxWanxPagination.defaultHLXPaginationOnBeforeEvent(showPageNum);

    const beforeConf: IControlPage = beforeFunc(currentPage, totalPage);

    const doms = new HLXCreatePaginationDom().create(txt, {
      ...beforeConf,
      totalPage,
    });

    const {
      previousPageBtn,
      nextPageBtn,
      page1Dom,
      beforeDots,
      pageDoms,
      afterDots,
      pageEndDom,
      prefixInputPage,
      inputPageDom,
      suffixInputPage,
      jumpPageBtn,
    } = doms;

    // ------------------------- 事件绑定 -------------------------

    // 上一页的点击事件
    if (!options.onClickPrevious) {
      console.error("没有设置上一页的点击事件");
    } else {
      previousPageBtn.addEventListener("click", options.onClickPrevious);
    }

    // 下一页的点击事件
    if (!options.onClickNext) {
      console.error("没有设置下一页的点击事件");
    } else {
      nextPageBtn.addEventListener("click", options.onClickNext);
    }

    // 跳转的点击事件
    if (!options.onClickGo) {
      console.error("没有设置跳转的点击事件");
    } else {
      jumpPageBtn.addEventListener("click", () => {
        if (!inputPageDom) return;
        if (!(inputPageDom as HTMLInputElement).value) return;

        const page = Number((inputPageDom as HTMLInputElement).value);
        if (isNaN(page)) return;

        if (options.onClickGo) options.onClickGo(page);
      });
    }

    // ------------------------- dom 装载 -------------------------

    renderDom.innerHTML = "";

    const addActiveClass = (dom: HTMLElement) => {
      dom.classList.add("active");
    };

    const onClickPage = (page: number) => () => {
      if (options.onClickPage) {
        options.onClickPage(page);
      } else {
        console.error("没有设置点击页码的事件");
      }
    };

    // 上一页
    renderDom.appendChild(previousPageBtn);

    // 分页单独用 div 包裹一层,方便 css 控制
    const pageContainer = document.createElement("div");
    pageContainer.classList.add("page-container");
    renderDom.appendChild(pageContainer);

    if (page1Dom) {
      pageContainer.appendChild(page1Dom);
      if (currentPage === 1) {
        addActiveClass(page1Dom);
      } else {
        page1Dom.addEventListener("click", onClickPage(1));
      }
    }
    pageContainer.appendChild(beforeDots);

    for (const pageDom of pageDoms) {
      const page = +pageDom.innerText;

      if (page === currentPage) {
        addActiveClass(pageDom);
      } else {
        pageDom.addEventListener("click", onClickPage(page));
      }

      pageContainer.appendChild(pageDom);
    }

    pageContainer.appendChild(afterDots);
    if (pageEndDom) {
      pageContainer.appendChild(pageEndDom);

      if (currentPage === totalPage) {
        addActiveClass(pageEndDom);
      } else {
        pageEndDom.addEventListener("click", onClickPage(totalPage));
      }
    }

    // 下一页
    renderDom.appendChild(nextPageBtn);

    // 跳转 单独用 div 包裹一层,方便 css 控制
    const jumpContainer = document.createElement("div");
    jumpContainer.classList.add("jump-container");
    renderDom.appendChild(jumpContainer);

    jumpContainer.appendChild(prefixInputPage);
    jumpContainer.appendChild(inputPageDom);
    jumpContainer.appendChild(suffixInputPage);
    jumpContainer.appendChild(jumpPageBtn);

    // ------------------------- after -------------------------

    const half = Math.floor((showPageNum - 1) / 2);

    // 第一页 + half + 有一个未显示的
    if (currentPage <= 1 + half + 1) {
      beforeDots.style.display = "none";
    }

    if (currentPage >= totalPage - half - 1) {
      afterDots.style.display = "none";
    }

    const afterFunc = options.onAfter;

    if (afterFunc) {
      afterFunc(
        { currentPage, totalPage, showPageNum, hrefList: [] },
        {
          previousPageBtn,
          nextPageBtn,

          pageContainer,
          page1Dom,
          beforeDots,
          pageDoms,
          afterDots,
          pageEndDom,

          jumpContainer,
          prefixInputPage,
          inputPageDom,
          suffixInputPage,
          jumpPageBtn,
        }
      );
    }
  }

  // ------------------------------------------------------------------------------------------------------------------------

  /**
   * hlx 正常页面的分页渲染
   */
  private renderByHlx(renderDom: Element) {
    const options = this.options;
    const { hlx = {}, txt = {}, conf = {} } = options;
    const showPageNum = conf.defaultShowPageNum || DEFAULT_SHOW_PAGE_NUM;

    let { current: _current, pages: _pages, href: _href } = hlx as IHlxConfig;

    if (!_current || isNaN(+_current)) {
      _current = 1;
    }

    if (!_pages || isNaN(+_pages)) {
      _pages = 1;
    }

    if (!_href || !Array.isArray(_href) || _href.length === 0) {
      _href = [window.location.href];
    }

    // 数据清洗
    const currentPage = +_current;
    const totalPage = +_pages;
    const hrefList = this.cleanHLXhref(_href, currentPage, totalPage);

    //   console.log("分页信息:", currentPage, totalPage, hrefList);

    // 通过 onBefore 事件 获取渲染前配置信息
    const beforeFunc =
      options.onBefore ||
      HlxWanxPagination.defaultHLXPaginationOnBeforeEvent(showPageNum);

    const beforeConf: IControlPage = beforeFunc(currentPage, totalPage);

    const doms = new HLXCreatePaginationDom().create(txt, {
      ...beforeConf,
      totalPage,
    });

    const {
      previousPageBtn,
      nextPageBtn,
      page1Dom,
      beforeDots,
      pageDoms,
      afterDots,
      pageEndDom,
      prefixInputPage,
      inputPageDom,
      suffixInputPage,
      jumpPageBtn,
    } = doms;

    // ------------------------- 事件绑定 -------------------------

    // 上一页的点击事件
    previousPageBtn.addEventListener("click", () => {
      if (options.onClickPrevious) {
        options.onClickPrevious();
      } else {
        const url = this.get_hlx_pagination_url(currentPage - 1, hrefList);
        if (url) {
          window.location.href = url;
        }
      }
    });

    // 下一页的点击事件
    nextPageBtn.addEventListener("click", () => {
      if (options.onClickNext) {
        options.onClickNext();
      } else {
        const url = this.get_hlx_pagination_url(currentPage + 1, hrefList);
        if (url) {
          window.location.href = url;
        }
      }
    });

    // 跳转的点击事件
    jumpPageBtn.addEventListener("click", () => {
      if (!inputPageDom) return;
      if (!(inputPageDom as HTMLInputElement).value) return;

      const page = Number((inputPageDom as HTMLInputElement).value);
      if (isNaN(page)) return;

      if (options.onClickGo) {
        options.onClickGo(page);
      } else {
        HlxWanxPagination.defaultHLXPaginationOnGoPage(page, {
          currentPage,
          totalPage,
          hrefList,
        });
      }
    });

    // ------------------------- dom 装载 -------------------------

    renderDom.innerHTML = "";

    const addActiveClass = (dom: HTMLElement) => {
      dom.classList.add("active");
    };

    // 上一页
    renderDom.appendChild(previousPageBtn);

    // 分页单独用 div 包裹一层,方便 css 控制
    const pageContainer = document.createElement("div");
    pageContainer.classList.add("page-container");
    renderDom.appendChild(pageContainer);

    if (page1Dom) {
      if (currentPage === 1) {
        addActiveClass(page1Dom);
      } else {
        page1Dom.href = this.get_hlx_pagination_url(1, hrefList);
      }

      pageContainer.appendChild(page1Dom);
    }

    pageContainer.appendChild(beforeDots);

    for (const pageDom of pageDoms) {
      const page = +pageDom.innerText;

      if (page === currentPage) {
        addActiveClass(pageDom);
      } else {
        pageDom.href = this.get_hlx_pagination_url(page, hrefList);
      }

      pageContainer.appendChild(pageDom);
    }

    pageContainer.appendChild(afterDots);
    if (pageEndDom) {
      pageContainer.appendChild(pageEndDom);

      if (currentPage === totalPage) {
        addActiveClass(pageEndDom);
      } else {
        pageEndDom.href = this.get_hlx_pagination_url(totalPage, hrefList);
      }
    }

    // 下一页
    renderDom.appendChild(nextPageBtn);

    // 跳转 单独用 div 包裹一层,方便 css 控制
    const jumpContainer = document.createElement("div");
    jumpContainer.classList.add("jump-container");
    renderDom.appendChild(jumpContainer);

    jumpContainer.appendChild(prefixInputPage);
    jumpContainer.appendChild(inputPageDom);
    jumpContainer.appendChild(suffixInputPage);
    jumpContainer.appendChild(jumpPageBtn);

    // ---------------------------------------------------------
    // 主要用于控制 部分 dom的 显示与隐藏

    const half = Math.floor((showPageNum - 1) / 2);

    // 第一页 + half + 有一个未显示的
    if (currentPage <= 1 + half + 1) {
      beforeDots.style.display = "none";
    }

    if (currentPage >= totalPage - half - 1) {
      afterDots.style.display = "none";
    }

    // ------------------------- after -------------------------

    if (options.onAfter) {
      options.onAfter(
        {
          showPageNum,
          currentPage,
          totalPage,
          hrefList,
        },
        {
          previousPageBtn,
          nextPageBtn,

          pageContainer,
          page1Dom,
          beforeDots,
          pageDoms,
          afterDots,
          pageEndDom,

          jumpContainer,
          prefixInputPage,
          inputPageDom,
          suffixInputPage,
          jumpPageBtn,
        }
      );
    }
  }

  /**
   * 清洗 hlx 分页链接
   *
   * 将 页数的顺序 与 分页链接 一一对应
   */
  private cleanHLXhref(
    hrefs: string | string[],
    current: number,
    total: number
  ) {
    let _hrefList: string[];

    if (Array.isArray(hrefs)) {
      _hrefList = hrefs;
    } else {
      _hrefList = hrefs.replace("[", "").replace("]", "").split(",");
    }

    const result = [];
    for (let i = 0; i < _hrefList.length; i++) {
      const url = _hrefList[i].trim();

      // 这里非常坑
      // hrefs 会带上 “上一页” 和 “下一页” 的 url

      // 在 current = 1 时候,href 的最后一个 url是 “下一页”
      // 在 current = 总页数 时,url 的第一个 url 是 “上一页”

      // 如果 current = n,n > 1 && n < 总页数 时:
      // url 的第一个和最后一个分别是 “上一页” 和 “下一页”

      if (current === 1) {
        if (_hrefList.length > 1 && i === _hrefList.length - 1) {
          continue;
        }
      } else if (current === total) {
        if (i === 0) {
          continue;
        }
      } else {
        if (i === 0 || i === _hrefList.length - 1) {
          continue;
        }
      }

      result.push(url);
    }

    return result;
  }

  /**
   * 获取分页 url
   */
  private get_hlx_pagination_url(page: number, hlx_href_list: string[]) {
    if (page <= 0) {
      return "";
    }

    // 页数是从 1 开始,array index 是从 0 开始
    const url = hlx_href_list[page - 1];

    if (!url) return "";

    return url;
  }

  // ------------------------------------------------------------------------------------------------------------------------

  /**
   * 根据 输入值 生成分页配置
   *
   * 比如 5
   *
   * 当 page = 1 时候,返回 { startPage: 1, endPage: 5 }
   * 当 page = 2 时候,返回 { startPage: 1, endPage: 5 }
   * 当 page = 3 时候,返回 { startPage: 1, endPage: 5 }
   * 当 page = 4 时候,返回 { startPage: 2, endPage: 6 }
   * 当 page = 5 时候,返回 { startPage: 3, endPage: 7 }
   */
  static defaultHLXPaginationOnBeforeEvent(showPageNum: number): IBeforeFunc {
    const half = Math.floor((showPageNum - 1) / 2);

    return (currentPage, totalPage) => {
      // 如果总页数小于显示页数,则显示所有页
      if (totalPage <= showPageNum) {
        return { startPage: 1, endPage: totalPage };
      }

      // 当前页过小,显示前 showPageNum 页
      if (currentPage <= half + 1) {
        return { startPage: 1, endPage: showPageNum };
      }

      // 当前页过大,显示后 showPageNum 页
      if (currentPage >= totalPage - half) {
        return { startPage: totalPage - showPageNum + 1, endPage: totalPage };
      }

      // 正常情况,当前页在中间
      return {
        startPage: currentPage - half,
        endPage: currentPage + half,
      };
    };
  }

  static defaultHLXPaginationOnGoPage: IOnGoPage = (
    page: number,
    { totalPage }
  ) => {
    if (page > totalPage) {
      // @ts-ignore
      if (HlxWanxDialog && HlxWanxDialog.show) {
        // @ts-ignore
        HlxWanxDialog.show({
          title: "提示",
          content: "页码超出范围",
          buttons: [{ text: "确定" }],
        });
      } else {
        alert("页码超出范围");
      }
      return;
    }

    const url = window.location.href;
    const index = url.lastIndexOf("/");
    const path = url.slice(0, index);

    let addr = url.slice(index);
    // 处理URL中 下划线 情况
    const underscoreIndex = addr.lastIndexOf("_");
    if (underscoreIndex > -1) {
      addr =
        addr.substring(0, underscoreIndex) +
        addr.substring(addr.indexOf(".", underscoreIndex));
    }

    const dot = addr.lastIndexOf(".");
    if (dot === -1) {
      console.error("无效的URL格式:未找到文件扩展名");
      return;
    }

    const addrName = addr.substring(0, dot);
    const addrExt = addr.substring(dot);

    let newUrl = `${path}${addrName}_${page}${addrExt}`;
    if (page <= 1) {
      newUrl = `${path}${addrName}${addrExt}`;
    }

    window.location.href = newUrl;
  };
}

// ------------------------------------------------------------------------------------------------------------------------
// HLXCreatePaginationDom ,纯粹的 DOM 生产操作
// ------------------------------------------------------------------------------------------------------------------------

/**
 * 跳转 x 页
 */
interface ICreateJumpPageConf {
  /**
   * 如:"到"
   */
  toPagePrefix?: string;

  /**
   * 如:"页"
   */
  toPageSuffix?: string;

  /**
   * 如:"跳转"
   */
  toPageTxt?: string;
}

interface ITxtConf extends ICreateJumpPageConf {
  nextPageTxt?: string;
  previousPageTxt?: string;
}

/**
 * 分页存在多种情况,以5页为例:
 * - 当前页为1,则显示1,2,3,4,5 ... 10
 * - 当分页在中间时,则显示 1 ... 3,4,5,6,7 ... 10
 * - 当前页为10,则显示 1 ... 6,7,8,9,10
 *
 * startPage 与 endPage 就是控制 中间循环多少个 DOM 的配置
 */
interface ICreatePageConf extends IControlPage {
  /**
   * 总页数
   */
  totalPage: number;
}

class HLXCreatePaginationDom {
  create(txt: ITxtConf, controlPage: ICreatePageConf) {
    const { startPage = 0, endPage = 0, totalPage = 0 } = controlPage;

    // 上一页
    const previousPageBtn = this.render_previous_page();
    if (typeof txt.previousPageTxt === "string") {
      previousPageBtn.innerHTML = txt.previousPageTxt;
    }

    let page1Dom = null;
    // 这个时候需要渲染第一页
    if (startPage > 1) {
      page1Dom = this.render_page_item(1);
    }

    // 前面的 ...
    const beforeDots = this.render_dots();
    beforeDots.classList.add("page-before-dots");

    // 创建 分页 dom
    const pageDoms = [];
    for (let i = startPage; i <= endPage; i++) {
      // 渲染分页
      const pageDom = this.render_page_item(i);
      pageDoms.push(pageDom);
    }

    // 后面的 ...
    const afterDots = this.render_dots();
    afterDots.classList.add("page-after-dots");

    let pageEndDom = null;
    if (endPage < totalPage) {
      // 渲染最后一页
      pageEndDom = this.render_page_item(totalPage);
    }

    // 下一页
    const nextPageBtn = this.render_next_page();
    if (typeof txt.nextPageTxt === "string") {
      nextPageBtn.innerHTML = txt.nextPageTxt;
    }

    // 跳转页
    const [prefixInputPage, inputPageDom, suffixInputPage, jumpPageBtn] =
      this.render_jump_page(txt);

    return {
      previousPageBtn, // 上一页
      page1Dom, // 1
      beforeDots, // ...
      pageDoms, // 假如是:3,4,5,6,7
      afterDots, // ...
      pageEndDom, // 假如是:10
      nextPageBtn, // 下一页
      prefixInputPage, // 到第
      inputPageDom, // 输入框
      suffixInputPage, // 页
      jumpPageBtn, // 跳转
    };
  }

  private render_previous_page() {
    const dom = document.createElement("a");
    dom.classList.add("previous-page");
    dom.innerHTML = "上一页";

    return dom;
  }

  private render_next_page() {
    const dom = document.createElement("a");
    dom.classList.add("next-page");
    dom.innerHTML = "下一页";

    return dom;
  }

  private render_page_item(i: number) {
    const dom = document.createElement("a");
    dom.classList.add("page");
    dom.innerHTML = i + "";
    // if (i === currentPage) {
    //   // 当前页
    //   dom.classList.add("active");
    // } else {
    //   dom.href = this.get_pagination_url(i, hrefList);
    // }
    return dom;
  }

  /**
   * 渲染跳转页
   */
  private render_jump_page(conf: ICreateJumpPageConf) {
    var inputPrefix =
      typeof conf.toPagePrefix === "string" ? conf.toPagePrefix : "到第";
    var inputSuffix =
      typeof conf.toPageSuffix === "string" ? conf.toPageSuffix : "页";
    var toPageTxt =
      typeof conf.toPageTxt === "string" ? conf.toPageTxt : "跳转";

    const prefix = document.createElement("span");
    prefix.innerHTML = inputPrefix;
    prefix.classList.add("jump-page-prefix");

    // 输入框
    const inputDom = document.createElement("input");
    inputDom.classList.add("jump-page-input");

    // 后缀
    const suffix = document.createElement("span");
    suffix.innerHTML = inputSuffix;
    suffix.classList.add("jump-page-suffix");

    // 跳转按钮
    const toPageBtn = document.createElement("button");
    toPageBtn.classList.add("jump-page-button");
    toPageBtn.innerHTML = toPageTxt;

    return [prefix, inputDom, suffix, toPageBtn];
  }

  /**
   * “...” 元素
   */
  private render_dots() {
    const dom = document.createElement("span");
    dom.innerHTML = "...";
    return dom;
  }
}

interface ICreatedPaginationDom {
  previousPageBtn: HTMLElement;
  page1Dom: HTMLElement | null;
  beforeDots: HTMLElement;
  pageDoms: HTMLElement[];
  afterDots: HTMLElement;
  pageEndDom: HTMLElement | null;
  nextPageBtn: HTMLElement;
  prefixInputPage: HTMLElement;
  inputPageDom: HTMLElement;
  suffixInputPage: HTMLElement;
  jumpPageBtn: HTMLElement;
}

export { HlxWanxPagination };