1/* 2 * Copyright (C) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16export class PageNation { 17 element: any; 18 pageInfo: any; 19 first: any; 20 prev: any; 21 next: any; 22 last: any; 23 inputBox: any; 24 btn: any; 25 list: any; 26 origin: HTMLElement | undefined; 27 static BtnBackColor = '#6C9BFA'; 28 static BtnColor = '#fff'; 29 constructor(selector: any, options = {}) { 30 selector!.innerHTML = ''; 31 //最大容器 32 this.element = selector; 33 // 默认值 34 this.pageInfo = { 35 current: 1, 36 total: 100, 37 pageSize: 15, 38 }; 39 //等待创建的元素 40 this.first = null; 41 this.prev = null; 42 this.next = null; 43 this.last = null; 44 // 输入框 45 this.inputBox = null; 46 // 跳转按钮 47 this.btn = null; 48 // 中间的按钮组 49 this.list = null; 50 this.setPageOptions(options); 51 this.setItemStyles(); 52 this.createPageElement(); 53 this.bindPageHtml(); 54 this.bindPageEvent(); 55 } 56 57 setPageOptions(options: any) { 58 // 当前页 59 this.pageInfo.current = options.current || 1; 60 // 一页显示多少条 61 this.pageInfo.pageSize = options.pageSize || 15; 62 if (options.totalpage) { 63 //用户传递了多少页 64 this.pageInfo.totalpage = options.totalpage; 65 } else { 66 //没有传递多少页 67 if (options.total) { 68 // 如果传递了总条数 69 this.pageInfo.totalpage = Math.ceil(options.total / this.pageInfo.pageSize); 70 } else { 71 // 如果没有传递总条数 72 this.pageInfo.totalpage = 9; 73 } 74 } 75 this.pageInfo.first = options.first || '<<'; 76 this.pageInfo.change = options.change || function () {}; 77 } 78 79 setElementStyles(ele: any, styles: any) { 80 for (let key in styles) { 81 ele.style[key] = styles[key]; 82 } 83 } 84 85 setItemStyles() { 86 this.setElementStyles(this.element, { 87 margin: '18px auto', 88 display: 'flex', 89 alignItems: 'center', 90 justifyContent: 'center', 91 }); 92 } 93 94 createElement(jumpDiv:HTMLElement):void{ 95 // Create input field 96 this.inputBox = document.createElement('input'); 97 this.inputBox.value = this.pageInfo.current; 98 this.setElementStyles(this.inputBox, { 99 width: '35px', 100 height: '30px', 101 textAlign: 'center', 102 outline: 'none', 103 padding: '0', 104 border: '0', 105 'border-radius': '5px', 106 }); 107 jumpDiv.appendChild(this.inputBox); 108 let span = document.createElement('span'); 109 span.style.width = '1px'; 110 span.style.height = '24px'; 111 span.style.alignSelf = 'center'; 112 span.style.backgroundColor = '#999999'; 113 jumpDiv.appendChild(span); 114 // Create button 115 this.btn = document.createElement('button'); 116 this.btn.innerText = ''; 117 this.btn.name = 'goto'; 118 this.setElementStyles(this.btn, { 119 height: '32px', 120 width: '30px', 121 cursor: 'pointer', 122 backgroundColor: '#FFF', 123 border: '0', 124 'border-radius': '5px', 125 }); 126 this.btn.style.background = `url('img/arrowright.png') no-repeat 98% center var(--dark-background3,#FFFFFF)`; 127 this.btn.style.backgroundPosition = 'center'; 128 jumpDiv.appendChild(this.btn); 129 this.element.appendChild(jumpDiv); 130 } 131 132 // 创建元素 首页 上一页 按钮组 下一页 尾页 输入框 按钮 133 createPageElement() { 134 //首页 135 this.origin = document.createElement('p'); 136 this.setElementStyles(this.origin, { 137 'border-radius': '4px', 138 padding: '5px', 139 border: '1px solid rgba(0,0,0,0.6)', 140 cursor: 'pointer', 141 margin: '0 5px', 142 }); 143 this.first = this.origin.cloneNode(true); 144 this.first.innerText = this.pageInfo.first; 145 this.first.name = 'first'; 146 this.element.appendChild(this.first); 147 this.prev = this.origin.cloneNode(true); 148 this.prev.innerText = '<'; 149 this.prev.name = 'prev'; 150 this.prev.style.padding = '5px 10px'; 151 this.element.appendChild(this.prev); 152 // 创建ul 153 this.list = document.createElement('ul'); 154 this.setElementStyles(this.list, { 155 display: 'flex', 156 padding: '0', 157 }); 158 this.element.appendChild(this.list); 159 this.next = this.origin.cloneNode(true); 160 this.next.innerText = '>'; 161 this.next.name = 'next'; 162 this.next.style.padding = '5px 10px'; 163 this.next.style.margin = '0px 5px'; 164 this.element.appendChild(this.next); 165 this.last = this.origin.cloneNode(true); 166 this.last.innerText = '>>'; 167 this.last.name = 'last'; 168 this.last.style.padding = '5px'; 169 this.last.style.margin = '0px 5px'; 170 this.element.appendChild(this.last); 171 let jumpDiv = document.createElement('div'); 172 jumpDiv.style.display = 'flex'; 173 jumpDiv.style.border = '1px solid rgba(0,0,0,0.6)'; 174 jumpDiv.style.borderRadius = '4px'; 175 jumpDiv.style.width = '70px'; 176 jumpDiv.style.height = '32px'; 177 jumpDiv.style.marginLeft = '10px'; 178 179 this.createElement(jumpDiv); 180 } 181 182 // 判断首页 上一页 下一页 尾页 是否可以点击 183 bindPageHtml() { 184 const { current, totalpage } = this.pageInfo; 185 const disable = { color: '#999999', cursor: 'not-allowed' }; 186 const enable = { 187 color: '#000', 188 cursor: 'pointer', 189 }; 190 // 判断当前页是否是第一页 如果是第一页 那么首页和上一页就不能点击 191 if (current <= 1) { 192 this.setElementStyles(this.first, disable); 193 this.setElementStyles(this.prev, disable); 194 } else { 195 this.setElementStyles(this.first, enable); 196 this.setElementStyles(this.prev, enable); 197 } 198 // 判断当前页是否是最后一页 如果是最后一页 那么下一页和尾页就不能点击 199 if (current >= totalpage) { 200 this.setElementStyles(this.next, disable); 201 this.setElementStyles(this.last, disable); 202 } else { 203 this.setElementStyles(this.next, enable); 204 this.setElementStyles(this.last, enable); 205 } 206 this.inputBox.value = current; 207 //渲染的时候判断ul列表的显示情况 208 this.bindPageList(); 209 this.pageInfo.change(this.pageInfo.current); 210 } 211 212 bindPageList() { 213 this.list.innerHTML = '';// clear ul its contents 214 const { pageSize, current, totalpage } = this.pageInfo;//Clean the ul before each load 215 const origin = document.createElement('li'); 216 origin.dataset.name = 'item'; 217 this.setElementStyles(origin, { 218 listStyle: 'none', 219 'border-radius': '4px', 220 border: '1px solid rgba(0,0,0,0.6)', 221 padding: '5px 10px', 222 margin: '0 5px', 223 cursor: 'pointer', 224 }); 225 if (totalpage <= 9) { 226 for (let i = 0; i < totalpage; i++) { 227 this.buildLi(origin, i, current); 228 } 229 return; 230 } 231 // Five on the left... Two on the right 232 if (this.bindLeftList(current, totalpage, origin)) { 233 return; 234 } 235 // The current page is larger than 5 pages and smaller than the last 5 pages 236 for (let index = 0; index < 2; index++) { 237 this.buildLi(origin, index, current); 238 } 239 let span = document.createElement('span'); 240 span.innerText = '...'; 241 this.list.appendChild(span); 242 for (let i = current - 3; i < current + 2; i++) { 243 this.buildLi(origin, i, current); 244 } 245 span = document.createElement('span'); 246 span.innerText = '...'; 247 this.list.appendChild(span); 248 for (let i = totalpage - 2; i < totalpage; i++) { 249 this.buildLi(origin, i, current); 250 } 251 } 252 253 private buildLi(origin: HTMLElement, i: number, current: number) { 254 const li = origin.cloneNode(true); 255 // @ts-ignore 256 li.innerText = i + 1; 257 if (i + 1 === current) { 258 this.setElementStyles(li, { 259 backgroundColor: PageNation.BtnBackColor, 260 color: PageNation.BtnColor, 261 }); 262 } 263 this.list.appendChild(li); 264 } 265 266 bindLeftList(current: number, totalpage: number, origin: HTMLElement): boolean { 267 let span; 268 if (current < 5) { 269 // 左边5个 中间 ... 右边2个 270 for (let index = 0; index < 5; index++) { 271 this.buildLi(origin, index, current); 272 } 273 span = document.createElement('span'); 274 span.innerText = '...'; 275 this.list.appendChild(span); 276 for (let index = totalpage - 2; index < totalpage; index++) { 277 this.buildLi(origin, index, current); 278 } 279 return true; 280 } 281 if (current == 5) { 282 // 左边5个 中间 ... 右边2个 283 for (let i = 0; i < 7; i++) { 284 this.buildLi(origin, i, current); 285 } 286 span = document.createElement('span'); 287 span.innerText = '...'; 288 this.list.appendChild(span); 289 290 for (let index = totalpage - 2; index < totalpage; index++) { 291 this.buildLi(origin, index, current); 292 } 293 return true; 294 } 295 // 当前页面 大于倒数第5页 296 if (current > totalpage - 4) { 297 // 左边5个 中间 ... 右边2个 298 for (let index = 0; index < 2; index++) { 299 this.buildLi(origin, index, current); 300 } 301 span = document.createElement('span'); 302 span.innerText = '...'; 303 this.list.appendChild(span); 304 for (let i = totalpage - 5; i < totalpage; i++) { 305 this.buildLi(origin, i, current); 306 } 307 return true; 308 } 309 if (current == totalpage - 4) { 310 // 左边5个 中间 ... 右边2个 311 this.nodeAppendChild(origin,current,span,totalpage); 312 return true; 313 } 314 return false; 315 } 316 317 nodeAppendChild(origin: HTMLElement,current: number,span: any,totalpage: number):void{ 318 for (let i = 0; i < 2; i++) { 319 this.buildLi(origin, i, current); 320 } 321 span = document.createElement('span'); 322 span.innerText = '...'; 323 this.list.appendChild(span); 324 for (let i = totalpage - 7; i < totalpage; i++) { 325 this.buildLi(origin, i, current); 326 } 327 } 328 329 bindPageEvent() { 330 this.element.addEventListener( 331 'click', 332 (event: { 333 target: { 334 name: string; 335 dataset: { name: string }; 336 innerText: number; 337 }; 338 }) => { 339 this.targetName(event); 340 if (event.target.name === 'goto') { 341 // 拿到你文本的内容 342 let page = this.inputBox.value - 0; 343 if (isNaN(page)) { 344 page = 1; 345 } 346 if (page <= 1) { 347 page = 1; 348 } 349 if (page >= this.pageInfo.totalpage) { 350 page = this.pageInfo.totalpage; 351 } 352 this.pageInfo.current = page; 353 this.bindPageHtml(); 354 } 355 if (event.target.dataset.name === 'item') { 356 this.pageInfo.current = event.target.innerText - 0; 357 this.bindPageHtml(); 358 } 359 } 360 ); 361 } 362 363 targetName(event:{ 364 target: { 365 name: string; 366 dataset: { name: string }; 367 innerText: number; 368 }; 369 }):void{ 370 if (event.target.name === 'first') { 371 if (this.pageInfo.current === 1) return; 372 this.pageInfo.current = 1; 373 this.bindPageHtml(); 374 } 375 if (event.target.name === 'prev') { 376 if (this.pageInfo.current === 1) return; 377 this.pageInfo.current--; 378 this.bindPageHtml(); 379 } 380 if (event.target.name === 'next') { 381 if (this.pageInfo.current === this.pageInfo.totalpage) return; 382 this.pageInfo.current++; 383 this.bindPageHtml(); 384 } 385 if (event.target.name === 'last') { 386 if (this.pageInfo.current === this.pageInfo.totalpage) return; 387 this.pageInfo.current = this.pageInfo.totalpage; 388 this.bindPageHtml(); 389 } 390 } 391} 392