分享实用的JavaScript代码库

时间:2023-03-08 19:00:38
  1 var keyCodeMap = {
2 8: 'Backspace',
3 9: 'Tab',
4 13: 'Enter',
5 16: 'Shift',
6 17: 'Ctrl',
7 18: 'Alt',
8 19: 'Pause',
9 20: 'Caps Lock',
10 27: 'Escape',
11 32: 'Space',
12 33: 'Page Up',
13 34: 'Page Down',
14 35: 'End',
15 36: 'Home',
16 37: 'Left',
17 38: 'Up',
18 39: 'Right',
19 40: 'Down',
20 42: 'Print Screen',
21 45: 'Insert',
22 46: 'Delete',
23 48: '0',
24 49: '1',
25 50: '2',
26 51: '3',
27 52: '4',
28 53: '5',
29 54: '6',
30 55: '7',
31 56: '8',
32 57: '9',
33 65: 'A',
34 66: 'B',
35 67: 'C',
36 68: 'D',
37 69: 'E',
38 70: 'F',
39 71: 'G',
40 72: 'H',
41 73: 'I',
42 74: 'J',
43 75: 'K',
44 76: 'L',
45 77: 'M',
46 78: 'N',
47 79: 'O',
48 80: 'P',
49 81: 'Q',
50 82: 'R',
51 83: 'S',
52 84: 'T',
53 85: 'U',
54 86: 'V',
55 87: 'W',
56 88: 'X',
57 89: 'Y',
58 90: 'Z',
59 91: 'Windows',
60 93: 'Right Click',
61 96: 'Numpad 0',
62 97: 'Numpad 1',
63 98: 'Numpad 2',
64 99: 'Numpad 3',
65 100: 'Numpad 4',
66 101: 'Numpad 5',
67 102: 'Numpad 6',
68 103: 'Numpad 7',
69 104: 'Numpad 8',
70 105: 'Numpad 9',
71 106: 'Numpad *',
72 107: 'Numpad +',
73 109: 'Numpad -',
74 110: 'Numpad .',
75 111: 'Numpad /',
76 112: 'F1',
77 113: 'F2',
78 114: 'F3',
79 115: 'F4',
80 116: 'F5',
81 117: 'F6',
82 118: 'F7',
83 119: 'F8',
84 120: 'F9',
85 121: 'F10',
86 122: 'F11',
87 123: 'F12',
88 144: 'Num Lock',
89 145: 'Scroll Lock',
90 182: 'My Computer',
91 183: 'My Calculator',
92 186: ';',
93 187: '=',
94 188: ',',
95 189: '-',
96 190: '.',
97 191: '/',
98 192: '`',
99 219: '[',
100 220: '\\',
101 221: ']',
102 222: '\''
103 };
104
105 // 数据请求封装
106 $.extend({
107 getJson: function (url, data, success) {//getJson--同步方法---获取会员信息,推荐人
108 return $.ajax({
109 url: url,
110 type: 'get',
111 dataType: 'json',
112 async: false,
113 cache: true,
114 data: data,
115 success: function (result) {
116 success(result);
117 }
118 });
119 },
120 getAsyncJson: function (url, data, success) {
121 return $.ajax({
122 url: url,
123 type: 'get',
124 dataType: 'json',
125 async: true,
126 cache: true,
127 data: data,
128 success: function (result) {
129 success(result);
130 }
131 });
132 },
133 postAsyncJson: function (url, data, success) {
134 return $.ajax({
135 url: url,
136 type: 'post',
137 dataType: 'json',
138 //contentType: "application/json",
139 beforeSend: function (xhr) {
140 xhr.setRequestHeader("XSRF-TOKEN",
141 $('input:hidden[name="__RequestVerificationToken"]').val());
142 },
143 async: true,
144 cache: false,
145 data: data,
146 success: function (result) {
147 success(result);
148 }
149 });
150 },
151 postAsyncContentJson: function (url, data, success) {
152 data = JSON.stringify(data);
153 return $.ajax({
154 url: url,
155 type: 'post',
156 dataType: 'json',
157 contentType: "application/json",
158 beforeSend: function (xhr) {
159 xhr.setRequestHeader("XSRF-TOKEN",
160 $('input:hidden[name="__RequestVerificationToken"]').val());
161 },
162 async: true,
163 cache: false,
164 data: data,
165 success: function (result) {
166 success(result);
167 }
168 });
169 },
170 postJson: function (url, data, success) {
171 return $.ajax({
172 url: url,
173 type: 'post',
174 dataType: 'json',
175 beforeSend: function (xhr) {
176 xhr.setRequestHeader("XSRF-TOKEN",
177 $('input:hidden[name="__RequestVerificationToken"]').val());
178 },
179 async: false,
180 cache: false,
181 data: data,
182 success: function (result) {
183 success(result);
184 }
185 });
186 },
187 getHtml: function (url, data, success) {
188 return $.ajax({
189 url: url,
190 type: 'get',
191 dataType: 'html',
192 async: false,
193 cache: false,
194 data: data,
195 success: function (result) {
196 success(result);
197 }
198 });
199 },
200 getAsyncHtml: function (url, data, success) {
201 return $.ajax({
202 url: url,
203 type: 'get',
204 dataType: 'html',
205 async: true,
206 cache: false,
207 data: data,
208 success: function (result) {
209 success(result);
210 }
211 });
212 },
213 postHtml: function (url, data, success) {
214 return $.ajax({
215 url: url,
216 type: 'post',
217 dataType: 'html',
218 async: true,
219 cache: false,
220 data: data,
221 success: function (result) {
222 success(eval(result));
223 }
224 });
225 },
226 commonUploadImg: function (fileToUploadId, uploadFileType, isCompress, success) {
227 if (!fileToUploadId) {
228 layer.msg('上传控件ID不能为空!');
229 return;
230 }
231 var formData = new FormData();
232 var files = $('#' + fileToUploadId)[0].files[0];
233 if (!files) {
234 layer.msg('请选择图片文件');
235 return;
236 }
237 if (files.size > 5242880) {
238 layer.msg('请上传小于5M以下的图片');
239 return;
240 }
241 if (files.type == 'image/jpeg' || files.type == 'image/png') {
242
243 } else {
244 layer.msg('请上传图片文件!');
245 return;
246 }
247 formData.append("file", files);
248 formData.append("userId", user_id);
249 formData.append("uploadFileType", uploadFileType);
250 formData.append("isCompress", isCompress);
251 $.ajax({
252 url: '',
253 type: "POST",
254 data: formData,
255 processData: false,
256 contentType: false,
257 async: false,
258 cache: false,
259 success: function (data) {
260 if (data && data.succeed) {
261 success(data.values);
262 }
263 else {
264 if (data.errmsg) {
265 layer.msg(data.errmsg);
266 }
267 else {
268 layer.msg('上传图片失败,请稍后再试!');
269 }
270 }
271 }
272 });
273 },
274 isNullOrWhiteSpace: function (str) {
275 // 判断字符串是否为null,还是空或是空字符串,返回true或false
276 try {
277 if (str != null || str != undefined)
278 str = str.replace(/\ +/g, "");
279 if (str == null || str == '' || str == undefined) {
280 return false;
281 }
282 else {
283 return true;
284 }
285 }
286 catch (ex) {
287 return false;
288 }
289 },
290 setCookie: function (c_name, value, expiredays) { //写cookies
291 var exdate = new Date();
292 exdate.setDate(exdate.getDate() + expiredays);
293 document.cookie = c_name + "=" + escape(value) + ((expiredays == null) ? "" : ";expires=" + exdate.toGMTString());
294 },
295 getCookie: function (name) { //读取cookies
296 var arr, reg = new RegExp("(^| )" + name + "=([^;]*)(;|$)");
297 if (arr = document.cookie.match(reg))
298 return (arr[2]);
299 else
300 return null;
301 },
302 delCookie: function (name) { //删除cookies
303 var exp = new Date();
304 exp.setTime(exp.getTime() - 1);
305 var cval = getCookie(name);
306 if (cval != null)
307 document.cookie = name + "=" + cval + ";expires=" + exp.toGMTString();
308 },
309 setLocalStorage: function (name, value) {// 写入LocalStorage
310 if (!window.localStorage) {
311 return false;
312 }
313 else {
314 var storage = window.localStorage;
315 storage.setItem(name, value);
316 }
317 },
318 getLocalStorage: function (name) { // 读取LocalStorage
319 if (!window.localStorage) {
320 return false;
321 }
322 else {
323 var storage = window.localStorage;
324 return storage.getItem(name);
325 }
326 },
327 removeLocalStorage: function (name) { // 删除LocalStorage
328 if (!window.localStorage) {
329 return false;
330 }
331 else {
332 if (name != null && name != '' && name != undefined) {
333 var storage = window.localStorage;
334 storage.removeItem(name);
335 }
336 }
337 },
338 minuteByDateTime: function (date) {
339 var timestamp = Date.parse(new Date(date));
340 date = timestamp / 1000;
341 //获取js 时间戳
342 var time = new Date().getTime();
343 //去掉 js 时间戳后三位,与php 时间戳保持一致
344 time = parseInt((time - date * 1000) / 1000);
345 //存储转换值
346 var s;
347 if (time < 60 * 1) {//十分钟内
348 return '刚刚';
349 } else if ((time < 60 * 60)) {
350 //超过十分钟少于1小时
351 s = Math.floor(time / 60);
352 return s + "分钟";
353 } else if ((time < 60 * 60 * 24) && (time >= 60 * 60)) {
354 //超过1小时少于24小时
355 s = Math.floor(time / 60 / 60);
356 return s + "小时";
357 } else if ((time < 60 * 60 * 24 * 3) && (time >= 60 * 60 * 24)) {
358 //超过1天少于3天内
359 s = Math.floor(time / 60 / 60 / 24);
360 return s + "天";
361 } else {
362 //超过3天
363 var date = new Date(parseInt(date) * 1000);
364 return date.getFullYear() + "/" + (date.getMonth() + 1) + "/" + date.getDate();
365 }
366 },
367 getQueryString: function () { // 获取URL参数
368 var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
369 var r = window.location.search.substr(1).match(reg); //获取url中"?"符后的字符串并正则匹配
370 var context = "";
371 if (r != null)
372 context = r[2];
373 reg = null;
374 r = null;
375 return context == null || context == "" || context == "undefined" ? "" : context;
376 },
377 newGuid: function () {
378 var guid = "";
379 for (var i = 1; i <= 32; i++) {
380 var n = Math.floor(Math.random() * 16.0).toString(16);
381 guid += n;
382 if ((i == 8) || (i == 12) || (i == 16) || (i == 20))
383 guid += "-";
384 }
385 return guid;
386 },
387 /**
388 *
389 * @desc 判断两个数组是否相等
390 * @param {Array} arr1
391 * @param {Array} arr2
392 * @return {Boolean}
393 */
394 arrayEqual: function (arr1, arr2) {
395 if (arr1 === arr2) return true;
396 if (arr1.length != arr2.length) return false;
397 for (var i = 0; i < arr1.length; ++i) {
398 if (arr1[i] !== arr2[i]) return false;
399 }
400 return true;
401 },
402 /**
403 *
404 * @desc 为元素添加class
405 * @param {HTMLElement} ele
406 * @param {String} cls
407 */
408 addClass: function (ele, cls) {
409 if (!hasClass(ele, cls)) {
410 ele.className += ' ' + cls;
411 }
412 },
413 /**
414 *
415 * @desc 判断元素是否有某个class
416 * @param {HTMLElement} ele
417 * @param {String} cls
418 * @return {Boolean}
419 */
420 hasClass: function (ele, cls) {
421 return (new RegExp('(\\s|^)' + cls + '(\\s|$)')).test(ele.className);
422 },
423 removeClass: function (ele, cls) {
424 if ($.hasClass(ele, cls)) {
425 var reg = new RegExp('(\\s|^)' + cls + '(\\s|$)');
426 ele.className = ele.className.replace(reg, ' ');
427 }
428 },
429 /**
430 *
431 * @desc 获取浏览器类型和版本
432 * @return {String}
433 */
434 getExplore: function () {
435 var sys = {},
436 ua = navigator.userAgent.toLowerCase(),
437 s;
438 (s = ua.match(/rv:([\d.]+)\) like gecko/)) ? sys.ie = s[1] :
439 (s = ua.match(/msie ([\d\.]+)/)) ? sys.ie = s[1] :
440 (s = ua.match(/edge\/([\d\.]+)/)) ? sys.edge = s[1] :
441 (s = ua.match(/firefox\/([\d\.]+)/)) ? sys.firefox = s[1] :
442 (s = ua.match(/(?:opera|opr).([\d\.]+)/)) ? sys.opera = s[1] :
443 (s = ua.match(/chrome\/([\d\.]+)/)) ? sys.chrome = s[1] :
444 (s = ua.match(/version\/([\d\.]+).*safari/)) ? sys.safari = s[1] : 0;
445 // 根据关系进行判断
446 if (sys.ie) return ('IE: ' + sys.ie)
447 if (sys.edge) return ('EDGE: ' + sys.edge)
448 if (sys.firefox) return ('Firefox: ' + sys.firefox)
449 if (sys.chrome) return ('Chrome: ' + sys.chrome)
450 if (sys.opera) return ('Opera: ' + sys.opera)
451 if (sys.safari) return ('Safari: ' + sys.safari)
452 return 'Unkonwn'
453 },
454 /**
455 *
456 * @desc 获取操作系统类型
457 * @return {String}
458 */
459 getOS: function () {
460 var userAgent = 'navigator' in window && 'userAgent' in navigator && navigator.userAgent.toLowerCase() || '';
461 var vendor = 'navigator' in window && 'vendor' in navigator && navigator.vendor.toLowerCase() || '';
462 var appVersion = 'navigator' in window && 'appVersion' in navigator && navigator.appVersion.toLowerCase() || '';
463 if (/mac/i.test(appVersion)) return 'MacOSX';
464 if (/win/i.test(appVersion)) return 'windows'
465 if (/linux/i.test(appVersion)) return 'linux'
466 if (/iphone/i.test(userAgent) || /ipad/i.test(userAgent) || /ipod/i.test(userAgent)) 'ios'
467 if (/android/i.test(userAgent)) return 'android'
468 if (/win/i.test(appVersion) && /phone/i.test(userAgent)) return 'windowsPhone'
469 },
470 /**
471 *
472 * @desc 获取滚动条距顶部的距离
473 */
474 getScrollTop: function () {
475 return (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;
476 },
477 /**
478 *
479 * @desc 获取一个元素的距离文档(document)的位置,类似jQ中的offset()
480 * @param {HTMLElement} ele
481 * @returns { {left: number, top: number} }
482 */
483 offset: function (ele) {
484 var pos = {
485 left: 0,
486 top: 0
487 };
488 while (ele) {
489 pos.left += ele.offsetLeft;
490 pos.top += ele.offsetTop;
491 ele = ele.offsetParent;
492 };
493 return pos;
494 },
495 /**
496 *
497 * @desc 设置滚动条距顶部的距离
498 */
499 setScrollTop: function (value) {
500 window.scrollTo(0, value);
501 return value;
502 },
503 /**
504 * @desc 根据keycode获得键名
505 * @param {Number} keycode
506 * @return {String}
507 */
508 getKeyName: function (keycode) {
509 if (keyCodeMap[keycode]) {
510 return keyCodeMap[keycode];
511 } else {
512 console.log('Unknow Key(Key Code:' + keycode + ')');
513 return '';
514 }
515 },
516 /**
517 * @desc 深拷贝,支持常见类型
518 * @param {Any} values
519 */
520 deepClone: function (values) {
521 var copy;
522 // Handle the 3 simple types, and null or undefined
523 if (null == values || "object" != typeof values) return values;
524 // Handle Date
525 if (values instanceof Date) {
526 copy = new Date();
527 copy.setTime(values.getTime());
528 return copy;
529 }
530 // Handle Array
531 if (values instanceof Array) {
532 copy = [];
533 for (var i = 0, len = values.length; i < len; i++) {
534 copy[i] = deepClone(values[i]);
535 }
536 return copy;
537 }
538 // Handle Object
539 if (values instanceof Object) {
540 copy = {};
541 for (var attr in values) {
542 if (values.hasOwnProperty(attr)) copy[attr] = deepClone(values[attr]);
543 }
544 return copy;
545 }
546 throw new Error("Unable to copy values! Its type isn't supported.");
547 },
548 /**
549 *
550 * @desc 判断`obj`是否为空
551 * @param {Object} obj
552 * @return {Boolean}
553 */
554 isEmptyObject: function (obj) {
555 if (!obj || typeof obj !== 'object' || Array.isArray(obj))
556 return false
557 return !Object.keys(obj).length
558 },
559 /**
560 *
561 * @desc 随机生成颜色
562 * @return {String}
563 */
564 randomColor: function () {
565 return '#' + ('00000' + (Math.random() * 0x1000000 << 0).toString(16)).slice(-6);
566 },
567 /**
568 *
569 * @desc 生成指定范围随机数
570 * @param {Number} min
571 * @param {Number} max
572 * @return {Number}
573 */
574 randomNum: function (min, max) {
575 return Math.floor(min + Math.random() * (max - min));
576 },
577 /**
578 *
579 * @desc 判断是否为邮箱地址
580 * @param {String} str
581 * @return {Boolean}
582 */
583 isEmail: function (str) {
584 return /\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*/.test(str);
585 },
586 /**
587 *
588 * @desc 判断是否为身份证号
589 * @param {String|Number} str
590 * @return {Boolean}
591 */
592 isIdCard: function (str) {
593 return /^(^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$)|(^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])((\d{4})|\d{3}[Xx])$)$/.test(str)
594 },
595 /**
596 *
597 * @desc 判断是否为手机号
598 * @param {String|Number} str
599 * @return {Boolean}
600 */
601 isPhoneNum: function (str) {
602 return /^(0|86|17951)?(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$/.test(str)
603 },
604 /**
605 *
606 * @desc 判断是否为URL地址
607 * @param {String} str
608 * @return {Boolean}
609 */
610 isUrl: function (str) {
611 return /[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/i.test(str);
612 },
613 /**
614 *
615 * @desc 现金额转大写
616 * @param {Number} n
617 * @return {String}
618 */
619 digitUppercase: function (n) {
620 var fraction = ['角', '分'];
621 var digit = [
622 '零', '壹', '贰', '叁', '肆',
623 '伍', '陆', '柒', '捌', '玖'
624 ];
625 var unit = [
626 ['元', '万', '亿'],
627 ['', '拾', '佰', '仟']
628 ];
629 var head = n < 0 ? '欠' : '';
630 n = Math.abs(n);
631 var s = '';
632 for (var i = 0; i < fraction.length; i++) {
633 s += (digit[Math.floor(n * 10 * Math.pow(10, i)) % 10] + fraction[i]).replace(/零./, '');
634 }
635 s = s || '整';
636 n = Math.floor(n);
637 for (var i = 0; i < unit[0].length && n > 0; i++) {
638 var p = '';
639 for (var j = 0; j < unit[1].length && n > 0; j++) {
640 p = digit[n % 10] + unit[1][j] + p;
641 n = Math.floor(n / 10);
642 }
643 s = p.replace(/(零.)*零$/, '').replace(/^$/, '零') + unit[0][i] + s;
644 }
645 return head + s.replace(/(零.)*零元/, '元')
646 .replace(/(零.)+/g, '零')
647 .replace(/^整$/, '零元整');
648 },
649 /**
650 *
651 * @desc 判断浏览器是否支持webP格式图片
652 * @return {Boolean}
653 */
654 isSupportWebP: function () {
655 return !![].map && document.createElement('canvas').toDataURL('image/webp').indexOf('data:image/webp') == 0;
656 },
657 /**
658 * @desc 格式化${startTime}距现在的已过时间
659 * @param {Date} startTime
660 * @return {String}
661 */
662 formatPassTime: function (startTime) {
663 var currentTime = Date.parse(new Date()),
664 time = currentTime - startTime,
665 day = parseInt(time / (1000 * 60 * 60 * 24)),
666 hour = parseInt(time / (1000 * 60 * 60)),
667 min = parseInt(time / (1000 * 60)),
668 month = parseInt(day / 30),
669 year = parseInt(month / 12);
670 if (year) return year + "年前"
671 if (month) return month + "个月前"
672 if (day) return day + "天前"
673 if (hour) return hour + "小时前"
674 if (min) return min + "分钟前"
675 else return '刚刚'
676 },
677 /**
678 *
679 * @desc 格式化现在距${endTime}的剩余时间
680 * @param {Date} endTime
681 * @return {String}
682 */
683 formatRemainTime: function (endTime) {
684 var startDate = new Date(); //开始时间
685 var endDate = new Date(endTime); //结束时间
686 var t = endDate.getTime() - startDate.getTime(); //时间差
687 var d = 0,
688 h = 0,
689 m = 0,
690 s = 0;
691 if (t >= 0) {
692 d = Math.floor(t / 1000 / 3600 / 24);
693 h = Math.floor(t / 1000 / 60 / 60 % 24);
694 m = Math.floor(t / 1000 / 60 % 60);
695 s = Math.floor(t / 1000 % 60);
696 }
697 return d + "天 " + h + "小时 " + m + "分钟 " + s + "秒";
698 },
699 /**
700 *
701 * @desc url参数转对象
702 * @param {String} url default: window.location.href
703 * @return {Object}
704 */
705 parseQueryString: function (url) {
706 url = url == null ? window.location.href : url
707 var search = url.substring(url.lastIndexOf('?') + 1)
708 if (!search) {
709 return {}
710 }
711 return JSON.parse('{"' + decodeURIComponent(search).replace(/"/g, '\\"').replace(/&/g, '","').replace(/=/g, '":"') + '"}')
712 },
713 /**
714 *
715 * @desc 对象序列化
716 * @param {Object} obj
717 * @return {String}
718 */
719 stringfyQueryString: function (obj) {
720 if (!obj) return '';
721 var pairs = [];
722 for (var key in obj) {
723 var value = obj[key];
724 if (value instanceof Array) {
725 for (var i = 0; i < value.length; ++i) {
726 pairs.push(encodeURIComponent(key + '[' + i + ']') + '=' + encodeURIComponent(value[i]));
727 }
728 continue;
729 }
730 pairs.push(encodeURIComponent(key) + '=' + encodeURIComponent(obj[key]));
731 }
732 return pairs.join('&');
733 },
734 /**
735 * @desc 函数节流。
736 * 适用于限制`resize`和`scroll`等函数的调用频率
737 *
738 * @param {Number} delay 0 或者更大的毫秒数。 对于事件回调,大约100或250毫秒(或更高)的延迟是最有用的。
739 * @param {Boolean} noTrailing 可选,默认为false。
740 * 如果noTrailing为true,当节流函数被调用,每过`delay`毫秒`callback`也将执行一次。
741 * 如果noTrailing为false或者未传入,`callback`将在最后一次调用节流函数后再执行一次.
742 * (延迟`delay`毫秒之后,节流函数没有被调用,内部计数器会复位)
743 * @param {Function} callback 延迟毫秒后执行的函数。`this`上下文和所有参数都是按原样传递的,
744 * 执行去节流功能时,调用`callback`。
745 * @param {Boolean} debounceMode 如果`debounceMode`为true,`clear`在`delay`ms后执行。
746 * 如果debounceMode是false,`callback`在`delay` ms之后执行。
747 *
748 * @return {Function} 新的节流函数
749 */
750 throttle: function (delay, noTrailing, callback, debounceMode) {
751 // After wrapper has stopped being called, this timeout ensures that
752 // `callback` is executed at the proper times in `throttle` and `end`
753 // debounce modes.
754 var timeoutID;
755 // Keep track of the last time `callback` was executed.
756 var lastExec = 0;
757 // `noTrailing` defaults to falsy.
758 if (typeof noTrailing !== 'boolean') {
759 debounceMode = callback;
760 callback = noTrailing;
761 noTrailing = undefined;
762 }
763 // The `wrapper` function encapsulates all of the throttling / debouncing
764 // functionality and when executed will limit the rate at which `callback`
765 // is executed.
766 function wrapper() {
767 var self = this;
768 var elapsed = Number(new Date()) - lastExec;
769 var args = arguments;
770 // Execute `callback` and update the `lastExec` timestamp.
771 function exec() {
772 lastExec = Number(new Date());
773 callback.apply(self, args);
774 }
775 // If `debounceMode` is true (at begin) this is used to clear the flag
776 // to allow future `callback` executions.
777 function clear() {
778 timeoutID = undefined;
779 }
780 if (debounceMode && !timeoutID) {
781 // Since `wrapper` is being called for the first time and
782 // `debounceMode` is true (at begin), execute `callback`.
783 exec();
784 }
785 // Clear any existing timeout.
786 if (timeoutID) {
787 clearTimeout(timeoutID);
788 }
789 if (debounceMode === undefined && elapsed > delay) {
790 // In throttle mode, if `delay` time has been exceeded, execute
791 // `callback`.
792 exec();
793 } else if (noTrailing !== true) {
794 // In trailing throttle mode, since `delay` time has not been
795 // exceeded, schedule `callback` to execute `delay` ms after most
796 // recent execution.
797 //
798 // If `debounceMode` is true (at begin), schedule `clear` to execute
799 // after `delay` ms.
800 //
801 // If `debounceMode` is false (at end), schedule `callback` to
802 // execute after `delay` ms.
803 timeoutID = setTimeout(debounceMode ? clear : exec, debounceMode === undefined ? delay - elapsed : delay);
804 }
805 }
806 // Return the wrapper function.
807 return wrapper;
808 }
809 });

调用:

$.getCookie('name');