【Widget】JavaScriptでページャーの裏側を作る【Pagination】


ページャを作るときのコアロジックをnpmに公開しました。
TSに書き直して一部変数名等々を書き換えています👀🥒

そのうちPagerを使ったWeb Componentを作るのもいいかもしれない…( ˘ω˘ )

追記:2021/07/23


ページャー(Pager, Pagination)を実装する時にコアになる部分をまとめておきたかったので忘備録。

配列で項目を管理する

const items = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

配列から、任意の量だけ項目を抽出する

const index = 0; // 現在のページ
const limit = 3; // 3個ずつ表示 

items.slice(index * limit, (index * limit) + limit); // => [1, 2, 3]
const index = 2; // 現在のページ
const limit = 2; // 2個ずつ表示 

items.slice(index * limit, (index * limit) + limit); // => [5, 6]

最大何ページあるか調べる

Math.ceil(items.length / limit); // => 4

Pagerコンストラクタを作る

class Pager {
    limit = 5; // 1ページあたり何項目表示するか
    index = 0; // 何ページ目か
    #items = []; // 保持する情報のリスト

    // 最大何ページか
    get max() {
        return Math.ceil(this.#items.length / this.limit);
    }

    // 現在のページ内容
    get page() {
        const {limit, index} = this;

        return this.#items.slice(index * limit, (index * limit) + limit);
    }

    /**
     * current
     * @param {number} _index 欲しいページ数
     * @returns {any[]} 表示させたい項目のリスト
     */
    current(_index) {
        this.index = _index;

        if (this.index < 0) {
            this.index = 0;
        }

        if (this.max <= this.index) {
            this.index = this.max - 1;
        }

        return this.page;
    }

    /**
     * @param {Iterable} items - リスト化したいイテラブルな値
     */
    constructor(items) {
        this.#items = [...items]; // sliceのためにArray化
    }
}

使ってみる

const pager = new Pager([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);

pager.current(1); // => [6, 7, 8, 9, 10]
pager.current(-1); // => [1, 2, 3, 4, 5]
pager.current(pager.max); // => [6, 7, 8, 9, 10]
pager.current(100); // => [6, 7, 8, 9, 10]
pager.max // => 2

pager.limit = 2; // 表示数を変更

pager.max // => 5
pager.current(1); // => [3, 4]
pager.current(200); // => [9, 10]
pager.page // => [9, 10]

pager.index = 3; // 現在のページ番号を変更

pager.page // => [7, 8]
pager.current(7); // => [7, 8]

indexとかlimitもアクセサー(get,set)にしてもいいかもしれないし、constructorのなかで一部の値をイミュータブルにしてもいいかもしれない👀