util.js 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. /**
  2. @Name:layui.util 工具集
  3. @Author:贤心
  4. @License:MIT
  5. */
  6. layui.define('jquery', function(exports){
  7. "use strict";
  8. var $ = layui.$
  9. //外部接口
  10. ,util = {
  11. //固定块
  12. fixbar: function(options){
  13. var ELEM = 'layui-fixbar', TOP_BAR = 'layui-fixbar-top'
  14. ,dom = $(document), body = $('body')
  15. ,is, timer;
  16. options = $.extend({
  17. showHeight: 200 //出现TOP的滚动条高度临界值
  18. }, options);
  19. options.bar1 = options.bar1 === true ? '' : options.bar1;
  20. options.bar2 = options.bar2 === true ? '' : options.bar2;
  21. options.bgcolor = options.bgcolor ? ('background-color:' + options.bgcolor) : '';
  22. var icon = [options.bar1, options.bar2, ''] //图标:信息、问号、TOP
  23. ,elem = $(['<ul class="'+ ELEM +'">'
  24. ,options.bar1 ? '<li class="layui-icon" lay-type="bar1" style="'+ options.bgcolor +'">'+ icon[0] +'</li>' : ''
  25. ,options.bar2 ? '<li class="layui-icon" lay-type="bar2" style="'+ options.bgcolor +'">'+ icon[1] +'</li>' : ''
  26. ,'<li class="layui-icon '+ TOP_BAR +'" lay-type="top" style="'+ options.bgcolor +'">'+ icon[2] +'</li>'
  27. ,'</ul>'].join(''))
  28. ,topBar = elem.find('.'+TOP_BAR)
  29. ,scroll = function(){
  30. var stop = dom.scrollTop();
  31. if(stop >= (options.showHeight)){
  32. is || (topBar.show(), is = 1);
  33. } else {
  34. is && (topBar.hide(), is = 0);
  35. }
  36. };
  37. if($('.'+ ELEM)[0]) return;
  38. typeof options.css === 'object' && elem.css(options.css);
  39. body.append(elem), scroll();
  40. //bar点击事件
  41. elem.find('li').on('click', function(){
  42. var othis = $(this), type = othis.attr('lay-type');
  43. if(type === 'top'){
  44. $('html,body').animate({
  45. scrollTop : 0
  46. }, 200);
  47. }
  48. options.click && options.click.call(this, type);
  49. });
  50. //Top显示控制
  51. dom.on('scroll', function(){
  52. clearTimeout(timer);
  53. timer = setTimeout(function(){
  54. scroll();
  55. }, 100);
  56. });
  57. }
  58. //倒计时
  59. ,countdown: function(endTime, serverTime, callback){
  60. var that = this
  61. ,type = typeof serverTime === 'function'
  62. ,end = new Date(endTime).getTime()
  63. ,now = new Date((!serverTime || type) ? new Date().getTime() : serverTime).getTime()
  64. ,count = end - now
  65. ,time = [
  66. Math.floor(count/(1000*60*60*24)) //天
  67. ,Math.floor(count/(1000*60*60)) % 24 //时
  68. ,Math.floor(count/(1000*60)) % 60 //分
  69. ,Math.floor(count/1000) % 60 //秒
  70. ];
  71. if(type) callback = serverTime;
  72. var timer = setTimeout(function(){
  73. that.countdown(endTime, now + 1000, callback);
  74. }, 1000);
  75. callback && callback(count > 0 ? time : [0,0,0,0], serverTime, timer);
  76. if(count <= 0) clearTimeout(timer);
  77. return timer;
  78. }
  79. //某个时间在当前时间的多久前
  80. ,timeAgo: function(time, onlyDate){
  81. var that = this
  82. ,arr = [[], []]
  83. ,stamp = new Date().getTime() - new Date(time).getTime();
  84. //返回具体日期
  85. if(stamp > 1000*60*60*24*8){
  86. stamp = new Date(time);
  87. arr[0][0] = that.digit(stamp.getFullYear(), 4);
  88. arr[0][1] = that.digit(stamp.getMonth() + 1);
  89. arr[0][2] = that.digit(stamp.getDate());
  90. //是否输出时间
  91. if(!onlyDate){
  92. arr[1][0] = that.digit(stamp.getHours());
  93. arr[1][1] = that.digit(stamp.getMinutes());
  94. arr[1][2] = that.digit(stamp.getSeconds());
  95. }
  96. return arr[0].join('-') + ' ' + arr[1].join(':');
  97. }
  98. //30天以内,返回“多久前”
  99. if(stamp >= 1000*60*60*24){
  100. return ((stamp/1000/60/60/24)|0) + '天前';
  101. } else if(stamp >= 1000*60*60){
  102. return ((stamp/1000/60/60)|0) + '小时前';
  103. } else if(stamp >= 1000*60*2){ //2分钟以内为:刚刚
  104. return ((stamp/1000/60)|0) + '分钟前';
  105. } else if(stamp < 0){
  106. return '未来';
  107. } else {
  108. return '刚刚';
  109. }
  110. }
  111. //数字前置补零
  112. ,digit: function(num, length){
  113. var str = '';
  114. num = String(num);
  115. length = length || 2;
  116. for(var i = num.length; i < length; i++){
  117. str += '0';
  118. }
  119. return num < Math.pow(10, length) ? str + (num|0) : num;
  120. }
  121. //转化为日期格式字符
  122. ,toDateString: function(time, format){
  123. var that = this
  124. ,date = new Date(time || new Date())
  125. ,ymd = [
  126. that.digit(date.getFullYear(), 4)
  127. ,that.digit(date.getMonth() + 1)
  128. ,that.digit(date.getDate())
  129. ]
  130. ,hms = [
  131. that.digit(date.getHours())
  132. ,that.digit(date.getMinutes())
  133. ,that.digit(date.getSeconds())
  134. ];
  135. format = format || 'yyyy-MM-dd HH:mm:ss';
  136. return format.replace(/yyyy/g, ymd[0])
  137. .replace(/MM/g, ymd[1])
  138. .replace(/dd/g, ymd[2])
  139. .replace(/HH/g, hms[0])
  140. .replace(/mm/g, hms[1])
  141. .replace(/ss/g, hms[2]);
  142. }
  143. //防 xss 攻击
  144. ,escape: function(html){
  145. return String(html || '').replace(/&(?!#?[a-zA-Z0-9]+;)/g, '&amp;')
  146. .replace(/</g, '&lt;').replace(/>/g, '&gt;')
  147. .replace(/'/g, '&#39;').replace(/"/g, '&quot;');
  148. }
  149. //批量事件
  150. ,event: function(attr, obj, eventType){
  151. obj = util.event[attr] = $.extend(true, util.event[attr], obj) || {};
  152. $('body').on(eventType || 'click', '*['+ attr +']', function(){
  153. var othis = $(this)
  154. ,key = othis.attr(attr);
  155. obj[key] && obj[key].call(this, othis);
  156. });
  157. }
  158. };
  159. //监听 DOM 尺寸变化,该创意来自:http://benalman.com/projects/jquery-resize-plugin/
  160. !function(a,b,c){"$:nomunge";function l(){f=b[g](function(){d.each(function(){var b=a(this),c=b.width(),d=b.height(),e=a.data(this,i);(c!==e.w||d!==e.h)&&b.trigger(h,[e.w=c,e.h=d])}),l()},e[j])}var f,d=a([]),e=a.resize=a.extend(a.resize,{}),g="setTimeout",h="resize",i=h+"-special-event",j="delay",k="throttleWindow";e[j]=250,e[k]=!0,a.event.special[h]={setup:function(){if(!e[k]&&this[g])return!1;var b=a(this);d=d.add(b),a.data(this,i,{w:b.width(),h:b.height()}),1===d.length&&l()},teardown:function(){if(!e[k]&&this[g])return!1;var b=a(this);d=d.not(b),b.removeData(i),d.length||clearTimeout(f)},add:function(b){function f(b,e,f){var g=a(this),h=a.data(this,i)||{};h.w=e!==c?e:g.width(),h.h=f!==c?f:g.height(),d.apply(this,arguments)}if(!e[k]&&this[g])return!1;var d;return a.isFunction(b)?(d=b,f):(d=b.handler,b.handler=f,void 0)}}}($,window);
  161. //暴露接口
  162. exports('util', util);
  163. });