page.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. (function () {
  2. var doc = document
  3. , id = 'getElementById'
  4. , tag = 'getElementsByTagName'
  5. //字符常量
  6. , MOD_NAME = 'laypage', DISABLED = 'layui-disabled'
  7. //构造器
  8. , Class = function (options) {
  9. var that = this;
  10. that.config = options || {};
  11. that.config.index = ++laypage.index;
  12. that.render(true);
  13. };
  14. //判断传入的容器类型
  15. Class.prototype.type = function () {
  16. var config = this.config;
  17. if (typeof config.elem === 'object') {
  18. return config.elem.length === undefined ? 2 : 3;
  19. }
  20. };
  21. //分页视图
  22. Class.prototype.view = function () {
  23. var that = this
  24. , config = that.config
  25. , groups = config.groups = 'groups' in config ? (config.groups | 0) : 5; //连续页码个数
  26. //排版
  27. config.layout = typeof config.layout === 'object'
  28. ? config.layout
  29. : ['prev', 'page', 'next'];
  30. config.count = config.count | 0; //数据总数
  31. config.curr = (config.curr | 0) || 1; //当前页
  32. //每页条数的选择项
  33. config.limits = typeof config.limits === 'object'
  34. ? config.limits
  35. : [10, 20, 30, 40, 50];
  36. config.limit = (config.limit | 0) || 10; //默认条数
  37. //总页数
  38. config.pages = Math.ceil(config.count / config.limit) || 1;
  39. //当前页不能超过总页数
  40. if (config.curr > config.pages) {
  41. config.curr = config.pages;
  42. }
  43. //连续分页个数不能低于0且不能大于总页数
  44. if (groups < 0) {
  45. groups = 1;
  46. } else if (groups > config.pages) {
  47. groups = config.pages;
  48. }
  49. config.prev = 'prev' in config ? config.prev : '&#x4E0A;&#x4E00;&#x9875;'; //上一页文本
  50. config.next = 'next' in config ? config.next : '&#x4E0B;&#x4E00;&#x9875;'; //下一页文本
  51. //计算当前组
  52. var index = config.pages > groups
  53. ? Math.ceil((config.curr + (groups > 1 ? 1 : 0)) / (groups > 0 ? groups : 1))
  54. : 1
  55. //试图片段
  56. , views = {
  57. //上一页
  58. prev: function () {
  59. return config.prev
  60. ? '<a href="javascript:;" class="layui-laypage-prev' + (config.curr == 1 ? (' ' + DISABLED) : '') + '" data-page="' + (config.curr - 1) + '">' + config.prev + '</a>'
  61. : '';
  62. }()
  63. //页码
  64. , page: function () {
  65. var pager = [];
  66. //数据量为0时,不输出页码
  67. if (config.count < 1) {
  68. return '';
  69. }
  70. //首页
  71. if (index > 1 && config.first !== false && groups !== 0) {
  72. pager.push('<a href="javascript:;" class="layui-laypage-first" data-page="1" title="&#x9996;&#x9875;">' + (config.first || 1) + '</a>');
  73. }
  74. //计算当前页码组的起始页
  75. var halve = Math.floor((groups - 1) / 2) //页码数等分
  76. , start = index > 1 ? config.curr - halve : 1
  77. , end = index > 1 ? (function () {
  78. var max = config.curr + (groups - halve - 1);
  79. return max > config.pages ? config.pages : max;
  80. }()) : groups;
  81. //防止最后一组出现“不规定”的连续页码数
  82. if (end - start < groups - 1) {
  83. start = end - groups + 1;
  84. }
  85. //输出左分割符
  86. if (config.first !== false && start > 2) {
  87. pager.push('<span class="layui-laypage-spr">&#x2026;</span>')
  88. }
  89. //输出连续页码
  90. for (; start <= end; start++) {
  91. if (start === config.curr) {
  92. //当前页
  93. pager.push('<span class="layui-laypage-curr"><em class="layui-laypage-em" ' + (/^#/.test(config.theme) ? 'style="background-color:' + config.theme + ';"' : '') + '></em><em>' + start + '</em></span>');
  94. } else {
  95. pager.push('<a href="javascript:;" data-page="' + start + '">' + start + '</a>');
  96. }
  97. }
  98. //输出输出右分隔符 & 末页
  99. if (config.pages > groups && config.pages > end && config.last !== false) {
  100. if (end + 1 < config.pages) {
  101. pager.push('<span class="layui-laypage-spr">&#x2026;</span>');
  102. }
  103. if (groups !== 0) {
  104. pager.push('<a href="javascript:;" class="layui-laypage-last" title="&#x5C3E;&#x9875;" data-page="' + config.pages + '">' + (config.last || config.pages) + '</a>');
  105. }
  106. }
  107. return pager.join('');
  108. }()
  109. //下一页
  110. , next: function () {
  111. return config.next
  112. ? '<a href="javascript:;" class="layui-laypage-next' + (config.curr == config.pages ? (' ' + DISABLED) : '') + '" data-page="' + (config.curr + 1) + '">' + config.next + '</a>'
  113. : '';
  114. }()
  115. //数据总数
  116. , count: '<span class="layui-laypage-count">共 ' + config.count + ' 条</span>'
  117. //每页条数
  118. , limit: function () {
  119. var options = ['<span class="layui-laypage-limits"><select lay-ignore>'];
  120. config.limits.forEach(function (item, index) {
  121. options.push(
  122. '<option value="' + item + '"'
  123. + (item === config.limit ? 'selected' : '')
  124. + '>' + item + ' 条/页</option>'
  125. );
  126. })
  127. return options.join('') + '</select></span>';
  128. }()
  129. //跳页区域
  130. , skip: function () {
  131. return ['<span class="layui-laypage-skip">&#x5230;&#x7B2C;'
  132. , '<input type="text" min="1" value="' + config.curr + '" class="layui-input">'
  133. , '&#x9875;<button type="button" class="layui-laypage-btn">&#x786e;&#x5b9a;</button>'
  134. , '</span>'].join('');
  135. }()
  136. };
  137. return ['<div class="layui-box layui-laypage layui-laypage-' + (config.theme ? (
  138. /^#/.test(config.theme) ? 'molv' : config.theme
  139. ) : 'default') + '" id="layui-laypage-' + config.index + '">'
  140. , function () {
  141. var plate = [];
  142. config.layout.forEach(function (item, index) {
  143. if (views[item]) {
  144. plate.push(views[item])
  145. }
  146. })
  147. return plate.join('');
  148. }()
  149. , '</div>'].join('');
  150. };
  151. //跳页的回调
  152. Class.prototype.jump = function (elem, isskip) {
  153. if (!elem) return;
  154. var that = this
  155. , config = that.config
  156. , childs = elem.children
  157. , btn = elem[tag]('button')[0]
  158. , input = elem[tag]('input')[0]
  159. , select = elem[tag]('select')[0]
  160. , skip = function () {
  161. var curr = input.value.replace(/\s|\D/g, '') | 0;
  162. if (curr) {
  163. config.curr = curr;
  164. that.render();
  165. }
  166. };
  167. if (isskip) return skip();
  168. //页码
  169. for (var i = 0, len = childs.length; i < len; i++) {
  170. if (childs[i].nodeName.toLowerCase() === 'a') {
  171. laypage.on(childs[i], 'click', function () {
  172. var curr = this.getAttribute('data-page') | 0;
  173. if (curr < 1 || curr > config.pages) return;
  174. config.curr = curr;
  175. that.render();
  176. });
  177. }
  178. }
  179. //条数
  180. if (select) {
  181. laypage.on(select, 'change', function () {
  182. var value = this.value;
  183. if (config.curr * value > config.count) {
  184. config.curr = Math.ceil(config.count / value);
  185. }
  186. config.limit = value;
  187. that.render();
  188. });
  189. }
  190. //确定
  191. if (btn) {
  192. laypage.on(btn, 'click', function () {
  193. skip();
  194. });
  195. }
  196. };
  197. //输入页数字控制
  198. Class.prototype.skip = function (elem) {
  199. if (!elem) return;
  200. var that = this, input = elem[tag]('input')[0];
  201. if (!input) return;
  202. laypage.on(input, 'keyup', function (e) {
  203. var value = this.value
  204. , keyCode = e.keyCode;
  205. if (/^(37|38|39|40)$/.test(keyCode)) return;
  206. if (/\D/.test(value)) {
  207. this.value = value.replace(/\D/, '');
  208. }
  209. if (keyCode === 13) {
  210. that.jump(elem, true)
  211. }
  212. });
  213. };
  214. //渲染分页
  215. Class.prototype.render = function (load) {
  216. var that = this
  217. , config = that.config
  218. , type = that.type()
  219. , view = that.view();
  220. if (type === 2) {
  221. config.elem && (config.elem.innerHTML = view);
  222. } else if (type === 3) {
  223. config.elem.html(view);
  224. } else {
  225. if (doc[id](config.elem)) {
  226. doc[id](config.elem).innerHTML = view;
  227. }
  228. }
  229. config.jump && config.jump(config, load);
  230. var elem = doc[id]('layui-laypage-' + config.index);
  231. that.jump(elem);
  232. if (config.hash && !load) {
  233. location.hash = '!' + config.hash + '=' + config.curr;
  234. }
  235. that.skip(elem);
  236. };
  237. //外部接口
  238. window.laypage = {
  239. //分页渲染
  240. render: function (options) {
  241. var o = new Class(options);
  242. return o.index;
  243. }
  244. , index: 0
  245. , on: function (elem, even, fn) {
  246. elem.attachEvent ? elem.attachEvent('on' + even, function (e) {
  247. fn.call(elem, e); //for ie
  248. }) : elem.addEventListener(even, fn, false);
  249. return this;
  250. }
  251. }
  252. })()