单例设计模式 return{}:

    • 这种模式只能支持 浏览器script导入进来
    • 不支持CommonJS模块规范,不支持webpack环境


    1. (function(){
    2. const css=function css(){};
    3. const offset=function offset(){}
    4. const throttle=function throttle(){}
    5. // 支持各种环境
    6. // 暴露API
    7. let utils={
    8. css,
    9. offset,
    10. throttle
    11. };
    12. // 浏览器
    13. if(typeof window!=="undefined") window.util=window._=utils;
    14. // 支持 CommonJs规范
    15. if(typeof module==="object"&&typeof module.exports==="object") module.exports=utils;
    16. })();
    1. (function () {
    2. var getProto = Object.getPrototypeOf;
    3. var class2type = {};
    4. var toString = class2type.toString;
    5. var hasOwn = class2type.hasOwnProperty;
    6. var fnToString = hasOwn.toString;
    7. var ObjectFunctionString = fnToString.call(Object);
    8. // 检测是否是一个函数
    9. var isFunction = function isFunction(obj) {
    10. return typeof obj === "function" && typeof obj.nodeType !== "number" &&
    11. typeof obj.item !== "function";
    12. };
    13. // 检测是否是一个window对象
    14. var isWindow = function isWindow(obj) {
    15. return obj != null && obj === obj.window;
    16. };
    17. // 标准的检测数据类型的办法
    18. var toType = function toType(obj) {
    19. if (obj == null) return obj + "";
    20. var reg = /^\[object ([a-zA-Z0-9]+)\]$/i;
    21. return typeof obj === "object" || typeof obj === "function" ?
    22. reg.exec(toString.call(obj))[1].toLowerCase() :
    23. typeof obj;
    24. };
    25. // 检测是否为数组或者类数组
    26. var isArrayLike = function isArrayLike(obj) {
    27. var length = !!obj && "length" in obj && obj.length,
    28. type = toType(obj);
    29. if (isFunction(obj) || isWindow(obj)) return false;
    30. return type === "array" || length === 0 ||
    31. typeof length === "number" && length > 0 && (length - 1) in obj;
    32. };
    33. // 检测是否为纯粹的对象「直属类是Object || Object.create(null)」
    34. var isPlainObject = function isPlainObject(obj) {
    35. var proto, Ctor;
    36. if (!obj || toString.call(obj) !== "[object Object]") return false;
    37. proto = getProto(obj);
    38. if (!proto) return true;
    39. Ctor = hasOwn.call(proto, "constructor") && proto.constructor;
    40. return typeof Ctor === "function" && fnToString.call(Ctor) === ObjectFunctionString;
    41. };
    42. // 检测是否是空对象
    43. var isEmptyObject = function isEmptyObject(obj) {
    44. var keys = Object.keys(obj);
    45. if (typeof Symbol !== "undefined") keys = keys.concat(Object.getOwnPropertySymbols(obj));
    46. return keys.length === 0;
    47. };
    48. // 检测是否是数字
    49. var isNumeric = function isNumeric(obj) {
    50. var type = toType(obj);
    51. return (type === "number" || type === "string") && !isNaN(obj);
    52. };
    53. /*
    54. * 获取元素样式
    55. */
    56. const getCss = function getCss(element, attr) {
    57. let value = window.getComputedStyle(element)[attr],
    58. reg = /^\d+(px|rem|em)?$/i;
    59. if (reg.test(value)) {
    60. value = parseFloat(value);
    61. }
    62. return value;
    63. };
    64. /*
    65. * 设置元素样式
    66. */
    67. const setCss = function setCss(element, attr, value) {
    68. if (attr === "opacity") {
    69. element['style']['opacity'] = value;
    70. element['style']['filter'] = `alpha(opacity=${value*100})`;
    71. return;
    72. }
    73. let reg = /^(width|height|margin|padding)?(top|left|bottom|right)?$/i;
    74. if (reg.test(attr)) {
    75. if (!isNaN(value)) {
    76. value += 'px';
    77. }
    78. }
    79. element['style'][attr] = value;
    80. };
    81. /*
    82. * 批量设置元素样式
    83. */
    84. const setGroupCss = function setGroupCss(element, options) {
    85. for (let key in options) {
    86. if (!options.hasOwnProperty(key)) break;
    87. setCss(element, key, options[key]);
    88. }
    89. };
    90. /*
    91. * 样式的综合处理
    92. */
    93. const css = function css(element) {
    94. let len = arguments.length,
    95. attr = arguments[1],
    96. value = arguments[2];
    97. if (len >= 3) {
    98. setCss(element, attr, value);
    99. return;
    100. }
    101. if (attr !== null && typeof attr === "object") {
    102. setGroupCss(element, attr);
    103. return;
    104. }
    105. return getCss(element, attr);
    106. };
    107. /*
    108. * 获取元素距离BODY的偏移量
    109. */
    110. const offset = function offset(element) {
    111. let parent = element.offsetParent,
    112. top = element.offsetTop,
    113. left = element.offsetLeft;
    114. while (parent) {
    115. if (!/MSIE 8/.test(navigator.userAgent)) {
    116. left += parent.clientLeft;
    117. top += parent.clientTop;
    118. }
    119. left += parent.offsetLeft;
    120. top += parent.offsetTop;
    121. parent = parent.offsetParent;
    122. }
    123. return {
    124. top,
    125. left
    126. };
    127. };
    128. /*
    129. * 函数防抖处理
    130. */
    131. const debounce = function debounce(func, wait, immediate) {
    132. if (typeof func !== "function") throw new TypeError('func must be an function');
    133. if (typeof wait === "boolean") {
    134. immediate = wait;
    135. wait = 300;
    136. }
    137. if (typeof wait !== "number") wait = 300;
    138. if (typeof immediate !== "boolean") immediate = false;
    139. let timer;
    140. return function proxy(...params) {
    141. let runNow = !timer && immediate,
    142. self = this,
    143. result;
    144. if (timer) {
    145. clearTimeout(timer);
    146. timer = null;
    147. }
    148. timer = setTimeout(() => {
    149. if (timer) {
    150. clearTimeout(timer);
    151. timer = null;
    152. }
    153. if (!immediate) result = func.call(self, ...params);
    154. }, wait);
    155. if (runNow) result = func.call(self, ...params);
    156. return result;
    157. };
    158. };
    159. /*
    160. * 函数节流处理
    161. */
    162. const throttle = function throttle(func, wait) {
    163. if (typeof func !== "function") throw new TypeError('func must be an function');
    164. if (typeof wait !== "number") wait = 300;
    165. let timer,
    166. previous = 0;
    167. return function proxy(...params) {
    168. let now = +new Date(),
    169. remaining = wait - (now - previous),
    170. self = this,
    171. result;
    172. if (remaining <= 0) {
    173. if (timer) {
    174. clearTimeout(timer);
    175. timer = null;
    176. }
    177. result = func.call(self, ...params);
    178. previous = now;
    179. } else if (!timer) {
    180. timer = setTimeout(() => {
    181. if (timer) {
    182. clearTimeout(timer);
    183. timer = null;
    184. }
    185. result = func.call(self, ...params);
    186. previous = +new Date();
    187. }, remaining);
    188. }
    189. return result;
    190. };
    191. };
    192. /* 暴露API */
    193. let utils = {
    194. debounce,
    195. throttle,
    196. offset,
    197. css,
    198. toType,
    199. isFunction,
    200. isWindow,
    201. isPlainObject,
    202. isArrayLike,
    203. isEmptyObject,
    204. isNumeric
    205. };
    206. let _$ = window.$;
    207. utils.noConflict = function noConflict() {
    208. if (window.$ === utils) window.$ = _$;
    209. return utils;
    210. };
    211. // 浏览器
    212. if(typeof window!=="undefined") window.util=window._=utils;
    213. // 支持 CommonJs规范
    214. if(typeof module==="object"&&typeof module.exports==="object") module.exports=utils;
    215. })();