@whitesev/data-paging 0.0.3 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/index.ts CHANGED
@@ -1,648 +1,648 @@
1
- import { PagingDefaultConfig } from "./config";
2
- import type { PagingConfig } from "./types/config";
3
- import { PagingUtils } from "./utils";
4
- import { version } from "./../package.json";
5
-
6
- export class Paging<T> {
7
- version = version;
8
- CONFIG;
9
- PAGE_CONFIG = {
10
- /**
11
- * 获取当前所在页
12
- */
13
- currentPage: () => {
14
- const $page = this.DOM_CONFIG.getAttributeWithCurrentPage();
15
- const page = this.DOM_CONFIG.getAttributeWithPageId($page!)!;
16
- // 如果未获取到元素,那么固定页码为1
17
- return page ?? 1;
18
- },
19
- /** 最大页码 */
20
- maxPage: 1,
21
- };
22
- DOM_CONFIG = {
23
- /* 整个分页元素 */
24
- $pageWrapper: {
25
- localName: "div",
26
- id: "data-paging-wrapper",
27
- dom: null as HTMLElement | null,
28
- },
29
- /* 第一页按钮 */
30
- firstBtnNode: {
31
- localName: "a",
32
- className: "pg-first",
33
- svgHTML: `<svg t="1694497357294" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4758" width="20"><path d="M730.639277 211.376748l60.943177 60.943176-301.698894 301.698893L428.940384 513.075641z" p-id="4759"></path><path d="M730.496772 814.924547l60.943176-60.943176-301.698893-301.698893L428.797879 513.225654z" p-id="4760"></path><path d="M298.666667 213.333333h85.333333v597.333334H298.666667z" p-id="4761"></path></svg>`,
34
- get: () => {
35
- return this.DOM_CONFIG.$pageWrapper.dom!.querySelector<HTMLAnchorElement>(
36
- `${this.DOM_CONFIG.firstBtnNode.localName}.${this.DOM_CONFIG.firstBtnNode.className}`
37
- )!;
38
- },
39
- },
40
- /* 上一页按钮 */
41
- prevBtnNode: {
42
- localName: "a",
43
- className: "pg-prev",
44
- svgHTML: `<svg t="1694497840770" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5272" width="20"><path d="M620.322607 151.04875l60.943176 60.943176-362.038672 362.038672L258.283935 513.087422z" p-id="5273"></path><path d="M620.180101 875.252545l60.943177-60.943176-362.038672-362.038672L258.141429 513.213873z" p-id="5274"></path></svg>`,
45
- get: () => {
46
- return this.DOM_CONFIG.$pageWrapper.dom!.querySelector<HTMLAnchorElement>(
47
- `${this.DOM_CONFIG.prevBtnNode.localName}.${this.DOM_CONFIG.prevBtnNode.className}`
48
- )!;
49
- },
50
- },
51
- /* 下一页按钮 */
52
- nextBtnNode: {
53
- localName: "a",
54
- className: "pg-next",
55
- svgHTML: `<svg t="1694497949481" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5465" width="20"><path d="M403.399239 151.02258l-60.943177 60.943177 362.038672 362.038672L765.437911 513.061252z" p-id="5466"></path><path d="M403.576858 875.263008l-60.943176-60.943176 362.038672-362.038672L765.61553 513.224336z" p-id="5467"></path></svg>`,
56
- get: () => {
57
- return this.DOM_CONFIG.$pageWrapper.dom!.querySelector<HTMLAnchorElement>(
58
- `${this.DOM_CONFIG.nextBtnNode.localName}.${this.DOM_CONFIG.nextBtnNode.className}`
59
- )!;
60
- },
61
- },
62
- /* 最后一页按钮 */
63
- lastBtnNode: {
64
- localName: "a",
65
- className: "pg-last",
66
- svgHTML: `<svg t="1694498035538" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2299" width="20"><path d="M516.266667 490.666667L256 230.4 315.733333 170.666667l320 320L315.733333 810.666667 256 750.933333l260.266667-260.266666zM678.4 170.666667h85.333333v640h-85.333333V170.666667z" p-id="2300"></path></svg>`,
67
- get: () => {
68
- return this.DOM_CONFIG.$pageWrapper.dom!.querySelector<HTMLAnchorElement>(
69
- `${this.DOM_CONFIG.lastBtnNode.localName}.${this.DOM_CONFIG.lastBtnNode.className}`
70
- )!;
71
- },
72
- },
73
- /**
74
- * 设置 元素的 页码 值
75
- * @param $el
76
- * @param page
77
- */
78
- setAttributeWithPageId: ($el: HTMLElement, page: number) => {
79
- $el.setAttribute("page-id", String(page));
80
- },
81
- /**
82
- * 获取 元素 的页码属性
83
- * @param $el
84
- */
85
- getAttributeWithPageId: ($el: HTMLElement) => {
86
- const pageId = $el?.getAttribute("page-id");
87
- return pageId ? parseInt(pageId) : null;
88
- },
89
- /**
90
- * 判断 元素 是否存在页码属性
91
- * @param $el
92
- */
93
- hasAttributeWithPageId: ($el: HTMLElement) => {
94
- return $el.hasAttribute("page-id");
95
- },
96
- /**
97
- * 设置 元素的属性 为当前所在页码
98
- * @param $el
99
- */
100
- setAttributeWithCurrentPage: ($el: HTMLElement) => {
101
- $el.setAttribute("data-current-page", "");
102
- },
103
- /**
104
- * 获取当前页码的元素
105
- * @param $pageWrapper
106
- */
107
- getAttributeWithCurrentPage: ($pageWrapper?: HTMLElement) => {
108
- return ($pageWrapper || this.DOM_CONFIG.$pageWrapper.dom!).querySelector<HTMLAnchorElement>(
109
- "a[data-current-page]"
110
- )!;
111
- },
112
- /**
113
- * 判断 元素 是否存在 当前页的属性
114
- * @param $el
115
- */
116
- hasAttributeWithCurrentPage: ($el: HTMLElement) => {
117
- return $el.hasAttribute("data-current-page");
118
- },
119
- /**
120
- * 移除 当前页码的属性
121
- * @param $el
122
- */
123
- removeAttributeWithCurrentPage: ($el: HTMLElement) => {
124
- $el.removeAttribute("data-current-page");
125
- },
126
- /**
127
- * 设置 元素 禁用
128
- * @param $el
129
- */
130
- setAttributeWithDisabled: ($el: HTMLElement) => {
131
- $el.setAttribute("disabled", "true");
132
- },
133
- /**
134
- * 移除当前页面的禁用的元素
135
- * @param $pageWrapper
136
- */
137
- removeAllAttributeWithDisabled: ($pageWrapper: HTMLElement | null) => {
138
- ($pageWrapper || this.DOM_CONFIG.$pageWrapper.dom!)
139
- ?.querySelectorAll<HTMLAnchorElement>("a[class][disabled]")
140
- .forEach((item) => {
141
- item.removeAttribute("disabled");
142
- });
143
- },
144
- /**
145
- * 获取 第一页 元素节点
146
- * @param $pageWrapper
147
- */
148
- getFirstPageNode: ($pageWrapper?: HTMLElement) => {
149
- return ($pageWrapper || this.DOM_CONFIG.$pageWrapper.dom!).querySelector<HTMLElement>("a[page-id='1']");
150
- },
151
- /**
152
- * 获取 最后一页 元素节点
153
- * @param {$pageWrapper
154
- */
155
- getLastPageNode: ($pageWrapper?: HTMLElement) => {
156
- return ($pageWrapper || this.DOM_CONFIG.$pageWrapper.dom!).querySelector<HTMLAnchorElement>(
157
- `a[page-id='${this.PAGE_CONFIG.maxPage}']`
158
- );
159
- },
160
- /**
161
- * 获取当前所有的页码元素节点
162
- * @param $pageWrapper
163
- */
164
- getAllPageNode: ($pageWrapper?: HTMLElement) => {
165
- return Array.from(
166
- ($pageWrapper || this.DOM_CONFIG.$pageWrapper.dom!).querySelectorAll<HTMLAnchorElement>("a[page-id]")
167
- );
168
- },
169
- };
170
- /**
171
- * @param config
172
- */
173
- constructor(config: PagingConfig<T>) {
174
- this.CONFIG = PagingDefaultConfig<T>();
175
- this.changeConfig(config);
176
- }
177
- /**
178
- * 隐藏分页容器
179
- * @param $wrapper 分页容器
180
- */
181
- hide($wrapper = this.DOM_CONFIG.$pageWrapper.dom) {
182
- if (!$wrapper) return;
183
- $wrapper.style.display = "none";
184
- }
185
- /**
186
- * 显示分页容器
187
- * @param $wrapper 分页容器
188
- */
189
- show($wrapper = this.DOM_CONFIG.$pageWrapper.dom) {
190
- if (!$wrapper) return;
191
- $wrapper.style.display = "";
192
- }
193
- /**
194
- * 判断分页容器是否隐藏
195
- * @param $wrapper 分页容器
196
- */
197
- isHide($wrapper = this.DOM_CONFIG.$pageWrapper.dom) {
198
- if (!$wrapper) return;
199
- return $wrapper.style.display.includes("none");
200
- }
201
- /**
202
- * 销毁分页容器
203
- */
204
- destory() {
205
- const $wrapper = this.DOM_CONFIG.$pageWrapper.dom;
206
- if (!$wrapper) return;
207
- const $parent = $wrapper.parentElement;
208
- $parent?.removeChild?.($wrapper);
209
- this.DOM_CONFIG.$pageWrapper.dom = null;
210
- }
211
- /**
212
- * 添加CSS
213
- * @param $parent 添加到目标元素
214
- */
215
- addCSS($parent: Node = document.head) {
216
- const $style = document.createElement("style");
217
- $style.setAttribute("type", "text/css");
218
- const cssText = /*css*/ `@charset "utf-8";
219
- #${this.DOM_CONFIG.$pageWrapper.id} {
220
- text-align: center;
221
- display: inline-block;
222
- }
223
- #${this.DOM_CONFIG.$pageWrapper.id} .${this.DOM_CONFIG.firstBtnNode.className},
224
- #${this.DOM_CONFIG.$pageWrapper.id} .${this.DOM_CONFIG.prevBtnNode.className},
225
- #${this.DOM_CONFIG.$pageWrapper.id} .${this.DOM_CONFIG.nextBtnNode.className},
226
- #${this.DOM_CONFIG.$pageWrapper.id} .${this.DOM_CONFIG.lastBtnNode.className} {
227
- font-family: Arial, sans-serif;
228
- color: #333;
229
- font-size: 22px;
230
- fill: currentColor;
231
- display: inline-flex;
232
- justify-content: center;
233
- align-items: center;
234
- text-decoration: none;
235
- }
236
- #${this.DOM_CONFIG.$pageWrapper.id} a,
237
- #${this.DOM_CONFIG.$pageWrapper.id} span {
238
- width: 45px;
239
- height: 40px;
240
- border: 1px solid #ebebeb;
241
- margin-left: -1px;
242
- color: #000000;
243
- line-height: 40px;
244
- float: left;
245
- font-size: 15px;
246
- text-decoration: none;
247
- margin: 0 2px;
248
- border-radius: 6px;
249
- }
250
- #${this.DOM_CONFIG.$pageWrapper.id} a:hover,
251
- #${this.DOM_CONFIG.$pageWrapper.id} span:hover {
252
- border-color: #3897cd;
253
- color: #3897cd;
254
- position: relative;
255
- z-index: 1;
256
- }
257
- #${this.DOM_CONFIG.$pageWrapper.id} a {
258
- cursor: pointer;
259
- user-select: none;
260
- }
261
- #${this.DOM_CONFIG.$pageWrapper.id} a[data-current-page] {
262
- background-color: #222a35;
263
- color: #fff;
264
- border-color: #ebebeb;
265
- position: relative;
266
- z-index: 1;
267
- }
268
- #${this.DOM_CONFIG.$pageWrapper.id} a.${this.DOM_CONFIG.firstBtnNode.className}[disabled="true"],
269
- #${this.DOM_CONFIG.$pageWrapper.id} a.${this.DOM_CONFIG.prevBtnNode.className}[disabled="true"],
270
- #${this.DOM_CONFIG.$pageWrapper.id} a.${this.DOM_CONFIG.nextBtnNode.className}[disabled="true"],
271
- #${this.DOM_CONFIG.$pageWrapper.id} a.${this.DOM_CONFIG.lastBtnNode.className}[disabled="true"]{
272
- cursor: not-allowed;
273
- border: 1px solid transparent;
274
- color: #c9c9c9;
275
- }
276
- `;
277
- PagingUtils.setSafeHTML($style, cssText);
278
- $parent.appendChild($style);
279
- }
280
- /**
281
- * 创建分页元素
282
- */
283
- createDataPagingWrapper() {
284
- const $pageWrapper = document.createElement(this.DOM_CONFIG.$pageWrapper.localName);
285
- this.DOM_CONFIG.$pageWrapper.dom = $pageWrapper;
286
- $pageWrapper.id = this.DOM_CONFIG.$pageWrapper.id;
287
- /* 第一页 */
288
- const $firstPage = document.createElement(this.DOM_CONFIG.firstBtnNode.localName);
289
- PagingUtils.setSafeHTML($firstPage, this.DOM_CONFIG.firstBtnNode.svgHTML);
290
- /* 上一页 */
291
- const $prevPage = document.createElement(this.DOM_CONFIG.prevBtnNode.localName);
292
- PagingUtils.setSafeHTML($prevPage, this.DOM_CONFIG.prevBtnNode.svgHTML);
293
- /* 下一页 */
294
- const $nextPage = document.createElement(this.DOM_CONFIG.nextBtnNode.localName);
295
- PagingUtils.setSafeHTML($nextPage, this.DOM_CONFIG.nextBtnNode.svgHTML);
296
- /* 最后一页 */
297
- const $lastPage = document.createElement(this.DOM_CONFIG.lastBtnNode.localName);
298
- PagingUtils.setSafeHTML($lastPage, this.DOM_CONFIG.lastBtnNode.svgHTML);
299
- $firstPage.className = this.DOM_CONFIG.firstBtnNode.className;
300
- $prevPage.className = this.DOM_CONFIG.prevBtnNode.className;
301
- $nextPage.className = this.DOM_CONFIG.nextBtnNode.className;
302
- $lastPage.className = this.DOM_CONFIG.lastBtnNode.className;
303
- /* 计算总数据量除以显示的数据量 得出分页的数量 */
304
- this.PAGE_CONFIG.maxPage = Math.ceil(this.CONFIG.data.length / this.CONFIG.pageShowDataMaxCount);
305
- /* 校正超出或小于的当前页码 */
306
- if (this.CONFIG.currentPage < 1) {
307
- this.CONFIG.currentPage = 1;
308
- } else if (this.CONFIG.currentPage > this.PAGE_CONFIG.maxPage) {
309
- this.CONFIG.currentPage = this.PAGE_CONFIG.maxPage;
310
- }
311
- /* 超过1 才开启分页 */
312
- if (this.PAGE_CONFIG.maxPage < 2) {
313
- return $pageWrapper;
314
- }
315
- /* 判断第一页按钮 是否开启 */
316
- if (this.CONFIG.firstBtn.enable) {
317
- this.setFirstBtnClickEvent($firstPage, $pageWrapper);
318
- $pageWrapper.appendChild($firstPage);
319
- }
320
- /* 判断上一页按钮 是否开启 */
321
- if (this.CONFIG.prevBtn.enable) {
322
- this.setPrevBtnClickEvent($prevPage, $pageWrapper);
323
- $pageWrapper.appendChild($prevPage);
324
- }
325
- let currentPage = this.CONFIG.currentPage;
326
- /* 计算出的最大页码在限制的显示页码数量内 */
327
- /* 比如计算出的页码总共有5个,设置中当前能显示出的页码按钮元素为3个 */
328
- if (this.CONFIG.pageMaxStep > this.PAGE_CONFIG.maxPage) {
329
- for (let index = currentPage; index <= this.PAGE_CONFIG.maxPage; index++) {
330
- const $page = document.createElement("a");
331
- this.DOM_CONFIG.setAttributeWithPageId($page, index);
332
- $page.innerText = String(index);
333
- if (this.CONFIG.currentPage === index) {
334
- this.DOM_CONFIG.setAttributeWithCurrentPage($page);
335
- }
336
- this.setPageBtnClickEvent($page, $pageWrapper);
337
- $pageWrapper.appendChild($page);
338
- }
339
- } else {
340
- /* 如果 当前页 + 限制显示的页码 大于等于 最大页,那么 从最后一页倒序着添加 */
341
- if (currentPage + this.CONFIG.pageMaxStep > this.PAGE_CONFIG.maxPage) {
342
- currentPage = this.PAGE_CONFIG.maxPage;
343
- const needAppendNodeList: Node[] = [];
344
- for (let index = 0; index < this.CONFIG.pageMaxStep; index++) {
345
- const $page = document.createElement("a");
346
- this.DOM_CONFIG.setAttributeWithPageId($page, currentPage);
347
- $page.innerText = String(currentPage);
348
- if (this.CONFIG.currentPage === currentPage) {
349
- this.DOM_CONFIG.setAttributeWithCurrentPage($page);
350
- }
351
- this.setPageBtnClickEvent($page, $pageWrapper);
352
- needAppendNodeList.push($page);
353
- currentPage--;
354
- }
355
- needAppendNodeList.reverse();
356
- needAppendNodeList.forEach((item) => {
357
- $pageWrapper.appendChild(item);
358
- });
359
- } else {
360
- /* 当前页 在计算出的页码内 */
361
- for (let index = 0; index < this.CONFIG.pageMaxStep; index++) {
362
- const $page = document.createElement("a");
363
- this.DOM_CONFIG.setAttributeWithPageId($page, currentPage);
364
- $page.innerText = String(currentPage);
365
- if (this.CONFIG.currentPage === currentPage) {
366
- this.DOM_CONFIG.setAttributeWithCurrentPage($page);
367
- }
368
- this.setPageBtnClickEvent($page, $pageWrapper);
369
- $pageWrapper.appendChild($page);
370
- currentPage++;
371
- }
372
- }
373
- }
374
- /* 判断下一页按钮 是否开启 */
375
- if (this.CONFIG.nextBtn.enable) {
376
- this.setNextBtnClickEvent($nextPage, $pageWrapper);
377
- $pageWrapper.appendChild($nextPage);
378
- }
379
- /* 判断最后一页按钮 是否开启 */
380
- if (this.CONFIG.lastBtn.enable) {
381
- this.setLastBtnClickEvent($lastPage, $pageWrapper);
382
- $pageWrapper.appendChild($lastPage);
383
- }
384
- /* 配置中的当前页码为1时 设置 第一页、上一页按钮禁用 */
385
- if (this.CONFIG.currentPage === 1) {
386
- this.DOM_CONFIG.setAttributeWithDisabled(this.DOM_CONFIG.firstBtnNode.get());
387
- this.DOM_CONFIG.setAttributeWithDisabled(this.DOM_CONFIG.prevBtnNode.get());
388
- } else if (this.CONFIG.currentPage === this.PAGE_CONFIG.maxPage) {
389
- /* 如果为最大的页码 下一页、最后一页禁用 */
390
- this.DOM_CONFIG.setAttributeWithDisabled(this.DOM_CONFIG.nextBtnNode.get());
391
- this.DOM_CONFIG.setAttributeWithDisabled(this.DOM_CONFIG.lastBtnNode.get());
392
- }
393
- return $pageWrapper;
394
- }
395
- /**
396
- * 设置 第一页 点击事件
397
- * @param $page 分页元素
398
- * @param $pageWrapper 分页按钮的容器元素
399
- */
400
- setFirstBtnClickEvent($page: HTMLElement, $pageWrapper: HTMLElement) {
401
- $page.addEventListener("click", async (event) => {
402
- const $currentPage = this.DOM_CONFIG.getAttributeWithCurrentPage();
403
- /* 当前页为第一页时无效 */
404
- if (this.DOM_CONFIG.getAttributeWithPageId($currentPage) === 1) {
405
- return;
406
- }
407
- await this.CONFIG.firstBtn?.callBack?.(event);
408
- const $allPage = this.DOM_CONFIG.getAllPageNode($pageWrapper);
409
- for (let index = 0; index < this.CONFIG.pageMaxStep; index++) {
410
- const $page = $allPage[index];
411
- if ($page == null) {
412
- continue;
413
- }
414
- /* 设置当前页码为第一页 */
415
- if (index === 0) {
416
- this.DOM_CONFIG.setAttributeWithCurrentPage($page);
417
- } else {
418
- /* 移除其它设置的第一页 */
419
- this.DOM_CONFIG.removeAttributeWithCurrentPage($page);
420
- }
421
- this.DOM_CONFIG.setAttributeWithPageId($page, index + 1);
422
- $page.innerText = String(index + 1);
423
- }
424
- this.DOM_CONFIG.removeAllAttributeWithDisabled($pageWrapper);
425
- /* 可视区域存在第一页的页码时,禁用第一页、上一页按钮 */
426
- if (this.DOM_CONFIG.getFirstPageNode($pageWrapper)) {
427
- this.DOM_CONFIG.setAttributeWithDisabled(this.DOM_CONFIG.firstBtnNode.get());
428
- this.DOM_CONFIG.setAttributeWithDisabled(this.DOM_CONFIG.prevBtnNode.get());
429
- }
430
- this.CONFIG.pageChangeCallBack(1);
431
- });
432
- }
433
- /**
434
- * 设置 上一页 点击事件
435
- * @param $page 分页元素
436
- * @param $pageWrapper 分页按钮的容器元素
437
- */
438
- setPrevBtnClickEvent($page: HTMLElement, $pageWrapper: HTMLElement) {
439
- $page.addEventListener("click", async (event) => {
440
- const $currentPage = this.DOM_CONFIG.getAttributeWithCurrentPage();
441
- /* 当前页为第一页时无效 */
442
- if (this.DOM_CONFIG.getAttributeWithPageId($currentPage) === 1) {
443
- return;
444
- }
445
- await this.CONFIG.prevBtn?.callBack?.(event);
446
- const $prev = $currentPage.previousElementSibling as HTMLElement | null;
447
- if ($prev && this.DOM_CONFIG.hasAttributeWithPageId($prev)) {
448
- $prev.click();
449
- } else {
450
- const $allPage = this.DOM_CONFIG.getAllPageNode($pageWrapper);
451
- $allPage.forEach((item) => {
452
- let page = this.DOM_CONFIG.getAttributeWithPageId(item)!;
453
- page--;
454
- this.DOM_CONFIG.setAttributeWithPageId(item, page);
455
- item.innerText = String(page);
456
- });
457
- this.CONFIG.pageChangeCallBack(this.PAGE_CONFIG.currentPage());
458
- }
459
- this.DOM_CONFIG.removeAllAttributeWithDisabled($pageWrapper);
460
- /* 如果当前第1页可见,且当前所在页不是第1页,则禁用上一页按钮和第一页按钮 */
461
- if (this.DOM_CONFIG.getFirstPageNode($pageWrapper) && this.PAGE_CONFIG.currentPage() == 1) {
462
- this.DOM_CONFIG.setAttributeWithDisabled(this.DOM_CONFIG.firstBtnNode.get());
463
- this.DOM_CONFIG.setAttributeWithDisabled(this.DOM_CONFIG.prevBtnNode.get());
464
- }
465
- });
466
- }
467
- /**
468
- * 设置 下一页 点击事件
469
- * @param $page 分页元素
470
- * @param $pageWrapper 分页按钮的容器元素
471
- */
472
- setNextBtnClickEvent($page: HTMLElement, $pageWrapper: HTMLElement) {
473
- $page.addEventListener("click", async (event) => {
474
- const $currentPage = this.DOM_CONFIG.getAttributeWithCurrentPage();
475
- /* 当前页出于最后一页时 无效点击 */
476
- if (this.DOM_CONFIG.getAttributeWithPageId($currentPage) === this.PAGE_CONFIG.maxPage) {
477
- return;
478
- }
479
- await this.CONFIG.nextBtn?.callBack?.(event);
480
- /* 如果后面的按钮存在页码属性 点击 */
481
- const $next = $currentPage.nextElementSibling as HTMLElement | null;
482
- if ($next && this.DOM_CONFIG.hasAttributeWithPageId($next)) {
483
- $next.click();
484
- } else {
485
- const allPageNode = this.DOM_CONFIG.getAllPageNode($pageWrapper);
486
- allPageNode.forEach((item) => {
487
- let page = this.DOM_CONFIG.getAttributeWithPageId(item)!;
488
- page++;
489
- if (page > this.PAGE_CONFIG.maxPage) {
490
- return;
491
- }
492
- this.DOM_CONFIG.setAttributeWithPageId(item, page);
493
- item.innerText = String(page);
494
- });
495
- this.CONFIG.pageChangeCallBack(this.PAGE_CONFIG.currentPage());
496
- }
497
- this.DOM_CONFIG.removeAllAttributeWithDisabled($pageWrapper);
498
- if (this.DOM_CONFIG.getLastPageNode() && this.PAGE_CONFIG.currentPage() == this.PAGE_CONFIG.maxPage) {
499
- this.DOM_CONFIG.setAttributeWithDisabled(this.DOM_CONFIG.nextBtnNode.get());
500
- this.DOM_CONFIG.setAttributeWithDisabled(this.DOM_CONFIG.lastBtnNode.get());
501
- }
502
- });
503
- }
504
- /**
505
- * 设置 最后一页 点击事件
506
- * @param $page 分页元素
507
- * @param $pageWrapper 分页按钮的容器元素
508
- */
509
- setLastBtnClickEvent($page: HTMLElement, $pageWrapper: HTMLElement) {
510
- $page.addEventListener("click", async (event) => {
511
- const $currentPage = this.DOM_CONFIG.getAttributeWithCurrentPage();
512
- if (this.DOM_CONFIG.getAttributeWithPageId($currentPage) === this.PAGE_CONFIG.maxPage) {
513
- return;
514
- }
515
- await this.CONFIG.lastBtn?.callBack?.(event);
516
- const $allPage = Array.from(this.DOM_CONFIG.getAllPageNode($pageWrapper));
517
- $allPage.reverse();
518
- let pageCount = this.PAGE_CONFIG.maxPage;
519
- let index = 0;
520
- while (true) {
521
- if (this.PAGE_CONFIG.maxPage - pageCount > 3) {
522
- break;
523
- }
524
- const $page = $allPage[index];
525
- if ($page == null) {
526
- break;
527
- }
528
- if (index === 0) {
529
- this.DOM_CONFIG.setAttributeWithCurrentPage($page);
530
- } else {
531
- this.DOM_CONFIG.removeAttributeWithCurrentPage($page);
532
- }
533
-
534
- this.DOM_CONFIG.setAttributeWithPageId($page, pageCount);
535
-
536
- $page.innerText = String(pageCount);
537
- pageCount--;
538
- index++;
539
- }
540
- this.DOM_CONFIG.removeAllAttributeWithDisabled($pageWrapper);
541
- this.DOM_CONFIG.setAttributeWithDisabled(this.DOM_CONFIG.nextBtnNode.get());
542
- this.DOM_CONFIG.setAttributeWithDisabled(this.DOM_CONFIG.lastBtnNode.get());
543
- this.CONFIG.pageChangeCallBack(this.PAGE_CONFIG.maxPage);
544
- });
545
- }
546
- /**
547
- * 设置 页 点击事件
548
- * @param $page 分页元素
549
- * @param $pageWrapper 分页按钮的容器元素
550
- */
551
- setPageBtnClickEvent($page: HTMLElement, $pageWrapper: HTMLElement) {
552
- $page.addEventListener("click", async () => {
553
- const $clickButton = $page;
554
- const $allPageList = this.DOM_CONFIG.getAllPageNode($pageWrapper);
555
- for (const item of $allPageList) {
556
- /* 是当前点击的页码 */
557
- if (item == $clickButton) {
558
- /* 如果 当前点击的页码不是current */
559
-
560
- if (!this.DOM_CONFIG.hasAttributeWithCurrentPage($clickButton)) {
561
- this.DOM_CONFIG.setAttributeWithCurrentPage($clickButton);
562
- const currentPage = this.PAGE_CONFIG.currentPage()!;
563
- await this.CONFIG?.pageChangeCallBack?.(currentPage);
564
- }
565
- } else {
566
- this.DOM_CONFIG.removeAttributeWithCurrentPage(item);
567
- }
568
- }
569
- this.DOM_CONFIG.removeAllAttributeWithDisabled($pageWrapper);
570
- /* 如果当前第1页可见,且当前所在页不是第1页,则禁用上一页按钮和第一页按钮 */
571
- if (this.DOM_CONFIG.getFirstPageNode($pageWrapper) && this.PAGE_CONFIG.currentPage() == 1) {
572
- this.DOM_CONFIG.setAttributeWithDisabled(this.DOM_CONFIG.firstBtnNode.get());
573
- this.DOM_CONFIG.setAttributeWithDisabled(this.DOM_CONFIG.prevBtnNode.get());
574
- }
575
- /* 如果当前最后一页可见,且当前所在页不是最后一页,则禁用下一页按钮和最后一页按钮 */
576
- if (this.DOM_CONFIG.getLastPageNode() && this.PAGE_CONFIG.currentPage() == this.PAGE_CONFIG.maxPage) {
577
- this.DOM_CONFIG.setAttributeWithDisabled(this.DOM_CONFIG.nextBtnNode.get());
578
- this.DOM_CONFIG.setAttributeWithDisabled(this.DOM_CONFIG.lastBtnNode.get());
579
- }
580
- });
581
- }
582
- /**
583
- * 把分页添加到某个父元素下
584
- * @param $parent
585
- */
586
- append($parent: Node) {
587
- const isHide = this.isHide();
588
- // 销毁旧的
589
- this.destory();
590
- const $pageWrapper = this.createDataPagingWrapper();
591
- if (isHide) {
592
- // 旧的是隐藏状态
593
- // 继承该状态
594
- this.hide($pageWrapper);
595
- }
596
- $parent.appendChild($pageWrapper);
597
- }
598
- /**
599
- * 把分页添加到某个元素之后
600
- */
601
- after($el: Element) {
602
- const isHide = this.isHide();
603
- const $parent = $el.parentElement;
604
- const $nextSlibling = $el.nextSibling;
605
- // 销毁旧的
606
- this.destory();
607
- const $pageWrapper = this.createDataPagingWrapper();
608
- if (isHide) {
609
- // 旧的是隐藏状态
610
- // 继承该状态
611
- this.hide($pageWrapper);
612
- }
613
- if (!$parent || $nextSlibling) {
614
- // 任意一个不行
615
- $el.after($pageWrapper);
616
- } else {
617
- $parent.insertBefore($pageWrapper, $nextSlibling);
618
- }
619
- }
620
- /**
621
- * 动态修改配置,注意,修改后需要.append修改原来的元素
622
- * @param config 配置
623
- */
624
- changeConfig(config: Partial<PagingConfig<T>>) {
625
- Object.assign(this.CONFIG, config);
626
- }
627
- /**
628
- * 刷新页面,重新渲染分页元素
629
- * @param data 新的数据
630
- * @example
631
- * 当总页数5页,当前在第3页,把第3页的数据删完,后面2页的数据会自动往前,需要重新计算数据
632
- * 且重新计算的数据的页数大于当前页(第3页)时,当前页不变,若小于当前页(第3页),则当前页为计算好的最大页
633
- */
634
- refresh(data: T[]) {
635
- this.CONFIG.data = [];
636
- this.CONFIG.data = data;
637
- let currentPage = this.PAGE_CONFIG.currentPage();
638
- const maxPage = Math.ceil(data.length / this.CONFIG.pageShowDataMaxCount);
639
- if (currentPage > maxPage) {
640
- currentPage = maxPage;
641
- }
642
- this.CONFIG.currentPage = currentPage;
643
- const $pageWrapper = this.DOM_CONFIG.$pageWrapper.dom;
644
- if ($pageWrapper) {
645
- this.after($pageWrapper);
646
- }
647
- }
648
- }
1
+ import { PagingDefaultConfig } from "./config";
2
+ import type { PagingConfig } from "./types/config";
3
+ import { PagingUtils } from "./utils";
4
+ import { version } from "./../package.json";
5
+
6
+ export class Paging<T> {
7
+ version = version;
8
+ CONFIG;
9
+ PAGE_CONFIG = {
10
+ /**
11
+ * 获取当前所在页
12
+ */
13
+ currentPage: () => {
14
+ const $page = this.DOM_CONFIG.getAttributeWithCurrentPage();
15
+ const page = this.DOM_CONFIG.getAttributeWithPageId($page!)!;
16
+ // 如果未获取到元素,那么固定页码为1
17
+ return page ?? 1;
18
+ },
19
+ /** 最大页码 */
20
+ maxPage: 1,
21
+ };
22
+ DOM_CONFIG = {
23
+ /* 整个分页元素 */
24
+ $pageWrapper: {
25
+ localName: "div",
26
+ id: "data-paging-wrapper",
27
+ dom: null as HTMLElement | null,
28
+ },
29
+ /* 第一页按钮 */
30
+ firstBtnNode: {
31
+ localName: "a",
32
+ className: "pg-first",
33
+ svgHTML: `<svg t="1694497357294" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4758" width="20"><path d="M730.639277 211.376748l60.943177 60.943176-301.698894 301.698893L428.940384 513.075641z" p-id="4759"></path><path d="M730.496772 814.924547l60.943176-60.943176-301.698893-301.698893L428.797879 513.225654z" p-id="4760"></path><path d="M298.666667 213.333333h85.333333v597.333334H298.666667z" p-id="4761"></path></svg>`,
34
+ get: () => {
35
+ return this.DOM_CONFIG.$pageWrapper.dom!.querySelector<HTMLAnchorElement>(
36
+ `${this.DOM_CONFIG.firstBtnNode.localName}.${this.DOM_CONFIG.firstBtnNode.className}`
37
+ )!;
38
+ },
39
+ },
40
+ /* 上一页按钮 */
41
+ prevBtnNode: {
42
+ localName: "a",
43
+ className: "pg-prev",
44
+ svgHTML: `<svg t="1694497840770" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5272" width="20"><path d="M620.322607 151.04875l60.943176 60.943176-362.038672 362.038672L258.283935 513.087422z" p-id="5273"></path><path d="M620.180101 875.252545l60.943177-60.943176-362.038672-362.038672L258.141429 513.213873z" p-id="5274"></path></svg>`,
45
+ get: () => {
46
+ return this.DOM_CONFIG.$pageWrapper.dom!.querySelector<HTMLAnchorElement>(
47
+ `${this.DOM_CONFIG.prevBtnNode.localName}.${this.DOM_CONFIG.prevBtnNode.className}`
48
+ )!;
49
+ },
50
+ },
51
+ /* 下一页按钮 */
52
+ nextBtnNode: {
53
+ localName: "a",
54
+ className: "pg-next",
55
+ svgHTML: `<svg t="1694497949481" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5465" width="20"><path d="M403.399239 151.02258l-60.943177 60.943177 362.038672 362.038672L765.437911 513.061252z" p-id="5466"></path><path d="M403.576858 875.263008l-60.943176-60.943176 362.038672-362.038672L765.61553 513.224336z" p-id="5467"></path></svg>`,
56
+ get: () => {
57
+ return this.DOM_CONFIG.$pageWrapper.dom!.querySelector<HTMLAnchorElement>(
58
+ `${this.DOM_CONFIG.nextBtnNode.localName}.${this.DOM_CONFIG.nextBtnNode.className}`
59
+ )!;
60
+ },
61
+ },
62
+ /* 最后一页按钮 */
63
+ lastBtnNode: {
64
+ localName: "a",
65
+ className: "pg-last",
66
+ svgHTML: `<svg t="1694498035538" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2299" width="20"><path d="M516.266667 490.666667L256 230.4 315.733333 170.666667l320 320L315.733333 810.666667 256 750.933333l260.266667-260.266666zM678.4 170.666667h85.333333v640h-85.333333V170.666667z" p-id="2300"></path></svg>`,
67
+ get: () => {
68
+ return this.DOM_CONFIG.$pageWrapper.dom!.querySelector<HTMLAnchorElement>(
69
+ `${this.DOM_CONFIG.lastBtnNode.localName}.${this.DOM_CONFIG.lastBtnNode.className}`
70
+ )!;
71
+ },
72
+ },
73
+ /**
74
+ * 设置 元素的 页码 值
75
+ * @param $el
76
+ * @param page
77
+ */
78
+ setAttributeWithPageId: ($el: HTMLElement, page: number) => {
79
+ $el.setAttribute("page-id", String(page));
80
+ },
81
+ /**
82
+ * 获取 元素 的页码属性
83
+ * @param $el
84
+ */
85
+ getAttributeWithPageId: ($el: HTMLElement) => {
86
+ const pageId = $el?.getAttribute("page-id");
87
+ return pageId ? parseInt(pageId) : null;
88
+ },
89
+ /**
90
+ * 判断 元素 是否存在页码属性
91
+ * @param $el
92
+ */
93
+ hasAttributeWithPageId: ($el: HTMLElement) => {
94
+ return $el.hasAttribute("page-id");
95
+ },
96
+ /**
97
+ * 设置 元素的属性 为当前所在页码
98
+ * @param $el
99
+ */
100
+ setAttributeWithCurrentPage: ($el: HTMLElement) => {
101
+ $el.setAttribute("data-current-page", "");
102
+ },
103
+ /**
104
+ * 获取当前页码的元素
105
+ * @param $pageWrapper
106
+ */
107
+ getAttributeWithCurrentPage: ($pageWrapper?: HTMLElement) => {
108
+ return ($pageWrapper || this.DOM_CONFIG.$pageWrapper.dom!).querySelector<HTMLAnchorElement>(
109
+ "a[data-current-page]"
110
+ )!;
111
+ },
112
+ /**
113
+ * 判断 元素 是否存在 当前页的属性
114
+ * @param $el
115
+ */
116
+ hasAttributeWithCurrentPage: ($el: HTMLElement) => {
117
+ return $el.hasAttribute("data-current-page");
118
+ },
119
+ /**
120
+ * 移除 当前页码的属性
121
+ * @param $el
122
+ */
123
+ removeAttributeWithCurrentPage: ($el: HTMLElement) => {
124
+ $el.removeAttribute("data-current-page");
125
+ },
126
+ /**
127
+ * 设置 元素 禁用
128
+ * @param $el
129
+ */
130
+ setAttributeWithDisabled: ($el: HTMLElement) => {
131
+ $el.setAttribute("disabled", "true");
132
+ },
133
+ /**
134
+ * 移除当前页面的禁用的元素
135
+ * @param $pageWrapper
136
+ */
137
+ removeAllAttributeWithDisabled: ($pageWrapper: HTMLElement | null) => {
138
+ ($pageWrapper || this.DOM_CONFIG.$pageWrapper.dom!)
139
+ ?.querySelectorAll<HTMLAnchorElement>("a[class][disabled]")
140
+ .forEach((item) => {
141
+ item.removeAttribute("disabled");
142
+ });
143
+ },
144
+ /**
145
+ * 获取 第一页 元素节点
146
+ * @param $pageWrapper
147
+ */
148
+ getFirstPageNode: ($pageWrapper?: HTMLElement) => {
149
+ return ($pageWrapper || this.DOM_CONFIG.$pageWrapper.dom!).querySelector<HTMLElement>("a[page-id='1']");
150
+ },
151
+ /**
152
+ * 获取 最后一页 元素节点
153
+ * @param {$pageWrapper
154
+ */
155
+ getLastPageNode: ($pageWrapper?: HTMLElement) => {
156
+ return ($pageWrapper || this.DOM_CONFIG.$pageWrapper.dom!).querySelector<HTMLAnchorElement>(
157
+ `a[page-id='${this.PAGE_CONFIG.maxPage}']`
158
+ );
159
+ },
160
+ /**
161
+ * 获取当前所有的页码元素节点
162
+ * @param $pageWrapper
163
+ */
164
+ getAllPageNode: ($pageWrapper?: HTMLElement) => {
165
+ return Array.from(
166
+ ($pageWrapper || this.DOM_CONFIG.$pageWrapper.dom!).querySelectorAll<HTMLAnchorElement>("a[page-id]")
167
+ );
168
+ },
169
+ };
170
+ /**
171
+ * @param config
172
+ */
173
+ constructor(config: PagingConfig<T>) {
174
+ this.CONFIG = PagingDefaultConfig<T>();
175
+ this.changeConfig(config);
176
+ }
177
+ /**
178
+ * 隐藏分页容器
179
+ * @param $wrapper 分页容器
180
+ */
181
+ hide($wrapper = this.DOM_CONFIG.$pageWrapper.dom) {
182
+ if (!$wrapper) return;
183
+ $wrapper.style.display = "none";
184
+ }
185
+ /**
186
+ * 显示分页容器
187
+ * @param $wrapper 分页容器
188
+ */
189
+ show($wrapper = this.DOM_CONFIG.$pageWrapper.dom) {
190
+ if (!$wrapper) return;
191
+ $wrapper.style.display = "";
192
+ }
193
+ /**
194
+ * 判断分页容器是否隐藏
195
+ * @param $wrapper 分页容器
196
+ */
197
+ isHide($wrapper = this.DOM_CONFIG.$pageWrapper.dom) {
198
+ if (!$wrapper) return;
199
+ return $wrapper.style.display.includes("none");
200
+ }
201
+ /**
202
+ * 销毁分页容器
203
+ */
204
+ destory() {
205
+ const $wrapper = this.DOM_CONFIG.$pageWrapper.dom;
206
+ if (!$wrapper) return;
207
+ const $parent = $wrapper.parentElement;
208
+ $parent?.removeChild?.($wrapper);
209
+ this.DOM_CONFIG.$pageWrapper.dom = null;
210
+ }
211
+ /**
212
+ * 添加CSS
213
+ * @param $parent 添加到目标元素
214
+ */
215
+ addCSS($parent: Node = document.head) {
216
+ const $style = document.createElement("style");
217
+ $style.setAttribute("type", "text/css");
218
+ const cssText = /*css*/ `@charset "utf-8";
219
+ #${this.DOM_CONFIG.$pageWrapper.id} {
220
+ text-align: center;
221
+ display: inline-block;
222
+ }
223
+ #${this.DOM_CONFIG.$pageWrapper.id} .${this.DOM_CONFIG.firstBtnNode.className},
224
+ #${this.DOM_CONFIG.$pageWrapper.id} .${this.DOM_CONFIG.prevBtnNode.className},
225
+ #${this.DOM_CONFIG.$pageWrapper.id} .${this.DOM_CONFIG.nextBtnNode.className},
226
+ #${this.DOM_CONFIG.$pageWrapper.id} .${this.DOM_CONFIG.lastBtnNode.className} {
227
+ font-family: Arial, sans-serif;
228
+ color: #333;
229
+ font-size: 22px;
230
+ fill: currentColor;
231
+ display: inline-flex;
232
+ justify-content: center;
233
+ align-items: center;
234
+ text-decoration: none;
235
+ }
236
+ #${this.DOM_CONFIG.$pageWrapper.id} a,
237
+ #${this.DOM_CONFIG.$pageWrapper.id} span {
238
+ width: 45px;
239
+ height: 40px;
240
+ border: 1px solid #ebebeb;
241
+ margin-left: -1px;
242
+ color: #000000;
243
+ line-height: 40px;
244
+ float: left;
245
+ font-size: 15px;
246
+ text-decoration: none;
247
+ margin: 0 2px;
248
+ border-radius: 6px;
249
+ }
250
+ #${this.DOM_CONFIG.$pageWrapper.id} a:hover,
251
+ #${this.DOM_CONFIG.$pageWrapper.id} span:hover {
252
+ border-color: #3897cd;
253
+ color: #3897cd;
254
+ position: relative;
255
+ z-index: 1;
256
+ }
257
+ #${this.DOM_CONFIG.$pageWrapper.id} a {
258
+ cursor: pointer;
259
+ user-select: none;
260
+ }
261
+ #${this.DOM_CONFIG.$pageWrapper.id} a[data-current-page] {
262
+ background-color: #222a35;
263
+ color: #fff;
264
+ border-color: #ebebeb;
265
+ position: relative;
266
+ z-index: 1;
267
+ }
268
+ #${this.DOM_CONFIG.$pageWrapper.id} a.${this.DOM_CONFIG.firstBtnNode.className}[disabled="true"],
269
+ #${this.DOM_CONFIG.$pageWrapper.id} a.${this.DOM_CONFIG.prevBtnNode.className}[disabled="true"],
270
+ #${this.DOM_CONFIG.$pageWrapper.id} a.${this.DOM_CONFIG.nextBtnNode.className}[disabled="true"],
271
+ #${this.DOM_CONFIG.$pageWrapper.id} a.${this.DOM_CONFIG.lastBtnNode.className}[disabled="true"]{
272
+ cursor: not-allowed;
273
+ border: 1px solid transparent;
274
+ color: #c9c9c9;
275
+ }
276
+ `;
277
+ PagingUtils.setSafeHTML($style, cssText);
278
+ $parent.appendChild($style);
279
+ }
280
+ /**
281
+ * 创建分页元素
282
+ */
283
+ createDataPagingWrapper() {
284
+ const $pageWrapper = document.createElement(this.DOM_CONFIG.$pageWrapper.localName);
285
+ this.DOM_CONFIG.$pageWrapper.dom = $pageWrapper;
286
+ $pageWrapper.id = this.DOM_CONFIG.$pageWrapper.id;
287
+ /* 第一页 */
288
+ const $firstPage = document.createElement(this.DOM_CONFIG.firstBtnNode.localName);
289
+ PagingUtils.setSafeHTML($firstPage, this.DOM_CONFIG.firstBtnNode.svgHTML);
290
+ /* 上一页 */
291
+ const $prevPage = document.createElement(this.DOM_CONFIG.prevBtnNode.localName);
292
+ PagingUtils.setSafeHTML($prevPage, this.DOM_CONFIG.prevBtnNode.svgHTML);
293
+ /* 下一页 */
294
+ const $nextPage = document.createElement(this.DOM_CONFIG.nextBtnNode.localName);
295
+ PagingUtils.setSafeHTML($nextPage, this.DOM_CONFIG.nextBtnNode.svgHTML);
296
+ /* 最后一页 */
297
+ const $lastPage = document.createElement(this.DOM_CONFIG.lastBtnNode.localName);
298
+ PagingUtils.setSafeHTML($lastPage, this.DOM_CONFIG.lastBtnNode.svgHTML);
299
+ $firstPage.className = this.DOM_CONFIG.firstBtnNode.className;
300
+ $prevPage.className = this.DOM_CONFIG.prevBtnNode.className;
301
+ $nextPage.className = this.DOM_CONFIG.nextBtnNode.className;
302
+ $lastPage.className = this.DOM_CONFIG.lastBtnNode.className;
303
+ /* 计算总数据量除以显示的数据量 得出分页的数量 */
304
+ this.PAGE_CONFIG.maxPage = Math.ceil(this.CONFIG.data.length / this.CONFIG.pageShowDataMaxCount);
305
+ /* 校正超出或小于的当前页码 */
306
+ if (this.CONFIG.currentPage < 1) {
307
+ this.CONFIG.currentPage = 1;
308
+ } else if (this.CONFIG.currentPage > this.PAGE_CONFIG.maxPage) {
309
+ this.CONFIG.currentPage = this.PAGE_CONFIG.maxPage;
310
+ }
311
+ /* 超过1 才开启分页 */
312
+ if (this.PAGE_CONFIG.maxPage < 2) {
313
+ return $pageWrapper;
314
+ }
315
+ /* 判断第一页按钮 是否开启 */
316
+ if (this.CONFIG.firstBtn.enable) {
317
+ this.setFirstBtnClickEvent($firstPage, $pageWrapper);
318
+ $pageWrapper.appendChild($firstPage);
319
+ }
320
+ /* 判断上一页按钮 是否开启 */
321
+ if (this.CONFIG.prevBtn.enable) {
322
+ this.setPrevBtnClickEvent($prevPage, $pageWrapper);
323
+ $pageWrapper.appendChild($prevPage);
324
+ }
325
+ let currentPage = this.CONFIG.currentPage;
326
+ /* 计算出的最大页码在限制的显示页码数量内 */
327
+ /* 比如计算出的页码总共有5个,设置中当前能显示出的页码按钮元素为3个 */
328
+ if (this.CONFIG.pageMaxStep > this.PAGE_CONFIG.maxPage) {
329
+ for (let index = currentPage; index <= this.PAGE_CONFIG.maxPage; index++) {
330
+ const $page = document.createElement("a");
331
+ this.DOM_CONFIG.setAttributeWithPageId($page, index);
332
+ $page.innerText = String(index);
333
+ if (this.CONFIG.currentPage === index) {
334
+ this.DOM_CONFIG.setAttributeWithCurrentPage($page);
335
+ }
336
+ this.setPageBtnClickEvent($page, $pageWrapper);
337
+ $pageWrapper.appendChild($page);
338
+ }
339
+ } else {
340
+ /* 如果 当前页 + 限制显示的页码 大于等于 最大页,那么 从最后一页倒序着添加 */
341
+ if (currentPage + this.CONFIG.pageMaxStep > this.PAGE_CONFIG.maxPage) {
342
+ currentPage = this.PAGE_CONFIG.maxPage;
343
+ const needAppendNodeList: Node[] = [];
344
+ for (let index = 0; index < this.CONFIG.pageMaxStep; index++) {
345
+ const $page = document.createElement("a");
346
+ this.DOM_CONFIG.setAttributeWithPageId($page, currentPage);
347
+ $page.innerText = String(currentPage);
348
+ if (this.CONFIG.currentPage === currentPage) {
349
+ this.DOM_CONFIG.setAttributeWithCurrentPage($page);
350
+ }
351
+ this.setPageBtnClickEvent($page, $pageWrapper);
352
+ needAppendNodeList.push($page);
353
+ currentPage--;
354
+ }
355
+ needAppendNodeList.reverse();
356
+ needAppendNodeList.forEach((item) => {
357
+ $pageWrapper.appendChild(item);
358
+ });
359
+ } else {
360
+ /* 当前页 在计算出的页码内 */
361
+ for (let index = 0; index < this.CONFIG.pageMaxStep; index++) {
362
+ const $page = document.createElement("a");
363
+ this.DOM_CONFIG.setAttributeWithPageId($page, currentPage);
364
+ $page.innerText = String(currentPage);
365
+ if (this.CONFIG.currentPage === currentPage) {
366
+ this.DOM_CONFIG.setAttributeWithCurrentPage($page);
367
+ }
368
+ this.setPageBtnClickEvent($page, $pageWrapper);
369
+ $pageWrapper.appendChild($page);
370
+ currentPage++;
371
+ }
372
+ }
373
+ }
374
+ /* 判断下一页按钮 是否开启 */
375
+ if (this.CONFIG.nextBtn.enable) {
376
+ this.setNextBtnClickEvent($nextPage, $pageWrapper);
377
+ $pageWrapper.appendChild($nextPage);
378
+ }
379
+ /* 判断最后一页按钮 是否开启 */
380
+ if (this.CONFIG.lastBtn.enable) {
381
+ this.setLastBtnClickEvent($lastPage, $pageWrapper);
382
+ $pageWrapper.appendChild($lastPage);
383
+ }
384
+ /* 配置中的当前页码为1时 设置 第一页、上一页按钮禁用 */
385
+ if (this.CONFIG.currentPage === 1) {
386
+ this.DOM_CONFIG.setAttributeWithDisabled(this.DOM_CONFIG.firstBtnNode.get());
387
+ this.DOM_CONFIG.setAttributeWithDisabled(this.DOM_CONFIG.prevBtnNode.get());
388
+ } else if (this.CONFIG.currentPage === this.PAGE_CONFIG.maxPage) {
389
+ /* 如果为最大的页码 下一页、最后一页禁用 */
390
+ this.DOM_CONFIG.setAttributeWithDisabled(this.DOM_CONFIG.nextBtnNode.get());
391
+ this.DOM_CONFIG.setAttributeWithDisabled(this.DOM_CONFIG.lastBtnNode.get());
392
+ }
393
+ return $pageWrapper;
394
+ }
395
+ /**
396
+ * 设置 第一页 点击事件
397
+ * @param $page 分页元素
398
+ * @param $pageWrapper 分页按钮的容器元素
399
+ */
400
+ setFirstBtnClickEvent($page: HTMLElement, $pageWrapper: HTMLElement) {
401
+ $page.addEventListener("click", async (event) => {
402
+ const $currentPage = this.DOM_CONFIG.getAttributeWithCurrentPage();
403
+ /* 当前页为第一页时无效 */
404
+ if (this.DOM_CONFIG.getAttributeWithPageId($currentPage) === 1) {
405
+ return;
406
+ }
407
+ await this.CONFIG.firstBtn?.callBack?.(event);
408
+ const $allPage = this.DOM_CONFIG.getAllPageNode($pageWrapper);
409
+ for (let index = 0; index < this.CONFIG.pageMaxStep; index++) {
410
+ const $page = $allPage[index];
411
+ if ($page == null) {
412
+ continue;
413
+ }
414
+ /* 设置当前页码为第一页 */
415
+ if (index === 0) {
416
+ this.DOM_CONFIG.setAttributeWithCurrentPage($page);
417
+ } else {
418
+ /* 移除其它设置的第一页 */
419
+ this.DOM_CONFIG.removeAttributeWithCurrentPage($page);
420
+ }
421
+ this.DOM_CONFIG.setAttributeWithPageId($page, index + 1);
422
+ $page.innerText = String(index + 1);
423
+ }
424
+ this.DOM_CONFIG.removeAllAttributeWithDisabled($pageWrapper);
425
+ /* 可视区域存在第一页的页码时,禁用第一页、上一页按钮 */
426
+ if (this.DOM_CONFIG.getFirstPageNode($pageWrapper)) {
427
+ this.DOM_CONFIG.setAttributeWithDisabled(this.DOM_CONFIG.firstBtnNode.get());
428
+ this.DOM_CONFIG.setAttributeWithDisabled(this.DOM_CONFIG.prevBtnNode.get());
429
+ }
430
+ this.CONFIG.pageChangeCallBack(1);
431
+ });
432
+ }
433
+ /**
434
+ * 设置 上一页 点击事件
435
+ * @param $page 分页元素
436
+ * @param $pageWrapper 分页按钮的容器元素
437
+ */
438
+ setPrevBtnClickEvent($page: HTMLElement, $pageWrapper: HTMLElement) {
439
+ $page.addEventListener("click", async (event) => {
440
+ const $currentPage = this.DOM_CONFIG.getAttributeWithCurrentPage();
441
+ /* 当前页为第一页时无效 */
442
+ if (this.DOM_CONFIG.getAttributeWithPageId($currentPage) === 1) {
443
+ return;
444
+ }
445
+ await this.CONFIG.prevBtn?.callBack?.(event);
446
+ const $prev = $currentPage.previousElementSibling as HTMLElement | null;
447
+ if ($prev && this.DOM_CONFIG.hasAttributeWithPageId($prev)) {
448
+ $prev.click();
449
+ } else {
450
+ const $allPage = this.DOM_CONFIG.getAllPageNode($pageWrapper);
451
+ $allPage.forEach((item) => {
452
+ let page = this.DOM_CONFIG.getAttributeWithPageId(item)!;
453
+ page--;
454
+ this.DOM_CONFIG.setAttributeWithPageId(item, page);
455
+ item.innerText = String(page);
456
+ });
457
+ this.CONFIG.pageChangeCallBack(this.PAGE_CONFIG.currentPage());
458
+ }
459
+ this.DOM_CONFIG.removeAllAttributeWithDisabled($pageWrapper);
460
+ /* 如果当前第1页可见,且当前所在页不是第1页,则禁用上一页按钮和第一页按钮 */
461
+ if (this.DOM_CONFIG.getFirstPageNode($pageWrapper) && this.PAGE_CONFIG.currentPage() == 1) {
462
+ this.DOM_CONFIG.setAttributeWithDisabled(this.DOM_CONFIG.firstBtnNode.get());
463
+ this.DOM_CONFIG.setAttributeWithDisabled(this.DOM_CONFIG.prevBtnNode.get());
464
+ }
465
+ });
466
+ }
467
+ /**
468
+ * 设置 下一页 点击事件
469
+ * @param $page 分页元素
470
+ * @param $pageWrapper 分页按钮的容器元素
471
+ */
472
+ setNextBtnClickEvent($page: HTMLElement, $pageWrapper: HTMLElement) {
473
+ $page.addEventListener("click", async (event) => {
474
+ const $currentPage = this.DOM_CONFIG.getAttributeWithCurrentPage();
475
+ /* 当前页出于最后一页时 无效点击 */
476
+ if (this.DOM_CONFIG.getAttributeWithPageId($currentPage) === this.PAGE_CONFIG.maxPage) {
477
+ return;
478
+ }
479
+ await this.CONFIG.nextBtn?.callBack?.(event);
480
+ /* 如果后面的按钮存在页码属性 点击 */
481
+ const $next = $currentPage.nextElementSibling as HTMLElement | null;
482
+ if ($next && this.DOM_CONFIG.hasAttributeWithPageId($next)) {
483
+ $next.click();
484
+ } else {
485
+ const allPageNode = this.DOM_CONFIG.getAllPageNode($pageWrapper);
486
+ allPageNode.forEach((item) => {
487
+ let page = this.DOM_CONFIG.getAttributeWithPageId(item)!;
488
+ page++;
489
+ if (page > this.PAGE_CONFIG.maxPage) {
490
+ return;
491
+ }
492
+ this.DOM_CONFIG.setAttributeWithPageId(item, page);
493
+ item.innerText = String(page);
494
+ });
495
+ this.CONFIG.pageChangeCallBack(this.PAGE_CONFIG.currentPage());
496
+ }
497
+ this.DOM_CONFIG.removeAllAttributeWithDisabled($pageWrapper);
498
+ if (this.DOM_CONFIG.getLastPageNode() && this.PAGE_CONFIG.currentPage() == this.PAGE_CONFIG.maxPage) {
499
+ this.DOM_CONFIG.setAttributeWithDisabled(this.DOM_CONFIG.nextBtnNode.get());
500
+ this.DOM_CONFIG.setAttributeWithDisabled(this.DOM_CONFIG.lastBtnNode.get());
501
+ }
502
+ });
503
+ }
504
+ /**
505
+ * 设置 最后一页 点击事件
506
+ * @param $page 分页元素
507
+ * @param $pageWrapper 分页按钮的容器元素
508
+ */
509
+ setLastBtnClickEvent($page: HTMLElement, $pageWrapper: HTMLElement) {
510
+ $page.addEventListener("click", async (event) => {
511
+ const $currentPage = this.DOM_CONFIG.getAttributeWithCurrentPage();
512
+ if (this.DOM_CONFIG.getAttributeWithPageId($currentPage) === this.PAGE_CONFIG.maxPage) {
513
+ return;
514
+ }
515
+ await this.CONFIG.lastBtn?.callBack?.(event);
516
+ const $allPage = Array.from(this.DOM_CONFIG.getAllPageNode($pageWrapper));
517
+ $allPage.reverse();
518
+ let pageCount = this.PAGE_CONFIG.maxPage;
519
+ let index = 0;
520
+ while (true) {
521
+ if (this.PAGE_CONFIG.maxPage - pageCount > 3) {
522
+ break;
523
+ }
524
+ const $page = $allPage[index];
525
+ if ($page == null) {
526
+ break;
527
+ }
528
+ if (index === 0) {
529
+ this.DOM_CONFIG.setAttributeWithCurrentPage($page);
530
+ } else {
531
+ this.DOM_CONFIG.removeAttributeWithCurrentPage($page);
532
+ }
533
+
534
+ this.DOM_CONFIG.setAttributeWithPageId($page, pageCount);
535
+
536
+ $page.innerText = String(pageCount);
537
+ pageCount--;
538
+ index++;
539
+ }
540
+ this.DOM_CONFIG.removeAllAttributeWithDisabled($pageWrapper);
541
+ this.DOM_CONFIG.setAttributeWithDisabled(this.DOM_CONFIG.nextBtnNode.get());
542
+ this.DOM_CONFIG.setAttributeWithDisabled(this.DOM_CONFIG.lastBtnNode.get());
543
+ this.CONFIG.pageChangeCallBack(this.PAGE_CONFIG.maxPage);
544
+ });
545
+ }
546
+ /**
547
+ * 设置 页 点击事件
548
+ * @param $page 分页元素
549
+ * @param $pageWrapper 分页按钮的容器元素
550
+ */
551
+ setPageBtnClickEvent($page: HTMLElement, $pageWrapper: HTMLElement) {
552
+ $page.addEventListener("click", async () => {
553
+ const $clickButton = $page;
554
+ const $allPageList = this.DOM_CONFIG.getAllPageNode($pageWrapper);
555
+ for (const item of $allPageList) {
556
+ /* 是当前点击的页码 */
557
+ if (item == $clickButton) {
558
+ /* 如果 当前点击的页码不是current */
559
+
560
+ if (!this.DOM_CONFIG.hasAttributeWithCurrentPage($clickButton)) {
561
+ this.DOM_CONFIG.setAttributeWithCurrentPage($clickButton);
562
+ const currentPage = this.PAGE_CONFIG.currentPage()!;
563
+ await this.CONFIG?.pageChangeCallBack?.(currentPage);
564
+ }
565
+ } else {
566
+ this.DOM_CONFIG.removeAttributeWithCurrentPage(item);
567
+ }
568
+ }
569
+ this.DOM_CONFIG.removeAllAttributeWithDisabled($pageWrapper);
570
+ /* 如果当前第1页可见,且当前所在页不是第1页,则禁用上一页按钮和第一页按钮 */
571
+ if (this.DOM_CONFIG.getFirstPageNode($pageWrapper) && this.PAGE_CONFIG.currentPage() == 1) {
572
+ this.DOM_CONFIG.setAttributeWithDisabled(this.DOM_CONFIG.firstBtnNode.get());
573
+ this.DOM_CONFIG.setAttributeWithDisabled(this.DOM_CONFIG.prevBtnNode.get());
574
+ }
575
+ /* 如果当前最后一页可见,且当前所在页不是最后一页,则禁用下一页按钮和最后一页按钮 */
576
+ if (this.DOM_CONFIG.getLastPageNode() && this.PAGE_CONFIG.currentPage() == this.PAGE_CONFIG.maxPage) {
577
+ this.DOM_CONFIG.setAttributeWithDisabled(this.DOM_CONFIG.nextBtnNode.get());
578
+ this.DOM_CONFIG.setAttributeWithDisabled(this.DOM_CONFIG.lastBtnNode.get());
579
+ }
580
+ });
581
+ }
582
+ /**
583
+ * 把分页添加到某个父元素下
584
+ * @param $parent
585
+ */
586
+ append($parent: Node) {
587
+ const isHide = this.isHide();
588
+ // 销毁旧的
589
+ this.destory();
590
+ const $pageWrapper = this.createDataPagingWrapper();
591
+ if (isHide) {
592
+ // 旧的是隐藏状态
593
+ // 继承该状态
594
+ this.hide($pageWrapper);
595
+ }
596
+ $parent.appendChild($pageWrapper);
597
+ }
598
+ /**
599
+ * 把分页添加到某个元素之后
600
+ */
601
+ after($el: Element) {
602
+ const isHide = this.isHide();
603
+ const $parent = $el.parentElement;
604
+ const $nextSlibling = $el.nextSibling;
605
+ // 销毁旧的
606
+ this.destory();
607
+ const $pageWrapper = this.createDataPagingWrapper();
608
+ if (isHide) {
609
+ // 旧的是隐藏状态
610
+ // 继承该状态
611
+ this.hide($pageWrapper);
612
+ }
613
+ if (!$parent || $nextSlibling) {
614
+ // 任意一个不行
615
+ $el.after($pageWrapper);
616
+ } else {
617
+ $parent.insertBefore($pageWrapper, $nextSlibling);
618
+ }
619
+ }
620
+ /**
621
+ * 动态修改配置,注意,修改后需要.append修改原来的元素
622
+ * @param config 配置
623
+ */
624
+ changeConfig(config: Partial<PagingConfig<T>>) {
625
+ Object.assign(this.CONFIG, config);
626
+ }
627
+ /**
628
+ * 刷新页面,重新渲染分页元素
629
+ * @param data 新的数据
630
+ * @example
631
+ * 当总页数5页,当前在第3页,把第3页的数据删完,后面2页的数据会自动往前,需要重新计算数据
632
+ * 且重新计算的数据的页数大于当前页(第3页)时,当前页不变,若小于当前页(第3页),则当前页为计算好的最大页
633
+ */
634
+ refresh(data: T[]) {
635
+ this.CONFIG.data = [];
636
+ this.CONFIG.data = data;
637
+ let currentPage = this.PAGE_CONFIG.currentPage();
638
+ const maxPage = Math.ceil(data.length / this.CONFIG.pageShowDataMaxCount);
639
+ if (currentPage > maxPage) {
640
+ currentPage = maxPage;
641
+ }
642
+ this.CONFIG.currentPage = currentPage;
643
+ const $pageWrapper = this.DOM_CONFIG.$pageWrapper.dom;
644
+ if ($pageWrapper) {
645
+ this.after($pageWrapper);
646
+ }
647
+ }
648
+ }