单例设计模式 return{}:
- 这种模式只能支持 浏览器script导入进来
- 不支持CommonJS模块规范,不支持webpack环境
(function(){const css=function css(){};const offset=function offset(){}const throttle=function throttle(){}// 支持各种环境// 暴露APIlet utils={css,offset,throttle};// 浏览器if(typeof window!=="undefined") window.util=window._=utils;// 支持 CommonJs规范if(typeof module==="object"&&typeof module.exports==="object") module.exports=utils;})();
(function () {var getProto = Object.getPrototypeOf;var class2type = {};var toString = class2type.toString;var hasOwn = class2type.hasOwnProperty;var fnToString = hasOwn.toString;var ObjectFunctionString = fnToString.call(Object);// 检测是否是一个函数var isFunction = function isFunction(obj) {return typeof obj === "function" && typeof obj.nodeType !== "number" &&typeof obj.item !== "function";};// 检测是否是一个window对象var isWindow = function isWindow(obj) {return obj != null && obj === obj.window;};// 标准的检测数据类型的办法var toType = function toType(obj) {if (obj == null) return obj + "";var reg = /^\[object ([a-zA-Z0-9]+)\]$/i;return typeof obj === "object" || typeof obj === "function" ?reg.exec(toString.call(obj))[1].toLowerCase() :typeof obj;};// 检测是否为数组或者类数组var isArrayLike = function isArrayLike(obj) {var length = !!obj && "length" in obj && obj.length,type = toType(obj);if (isFunction(obj) || isWindow(obj)) return false;return type === "array" || length === 0 ||typeof length === "number" && length > 0 && (length - 1) in obj;};// 检测是否为纯粹的对象「直属类是Object || Object.create(null)」var isPlainObject = function isPlainObject(obj) {var proto, Ctor;if (!obj || toString.call(obj) !== "[object Object]") return false;proto = getProto(obj);if (!proto) return true;Ctor = hasOwn.call(proto, "constructor") && proto.constructor;return typeof Ctor === "function" && fnToString.call(Ctor) === ObjectFunctionString;};// 检测是否是空对象var isEmptyObject = function isEmptyObject(obj) {var keys = Object.keys(obj);if (typeof Symbol !== "undefined") keys = keys.concat(Object.getOwnPropertySymbols(obj));return keys.length === 0;};// 检测是否是数字var isNumeric = function isNumeric(obj) {var type = toType(obj);return (type === "number" || type === "string") && !isNaN(obj);};/** 获取元素样式*/const getCss = function getCss(element, attr) {let value = window.getComputedStyle(element)[attr],reg = /^\d+(px|rem|em)?$/i;if (reg.test(value)) {value = parseFloat(value);}return value;};/** 设置元素样式*/const setCss = function setCss(element, attr, value) {if (attr === "opacity") {element['style']['opacity'] = value;element['style']['filter'] = `alpha(opacity=${value*100})`;return;}let reg = /^(width|height|margin|padding)?(top|left|bottom|right)?$/i;if (reg.test(attr)) {if (!isNaN(value)) {value += 'px';}}element['style'][attr] = value;};/** 批量设置元素样式*/const setGroupCss = function setGroupCss(element, options) {for (let key in options) {if (!options.hasOwnProperty(key)) break;setCss(element, key, options[key]);}};/** 样式的综合处理*/const css = function css(element) {let len = arguments.length,attr = arguments[1],value = arguments[2];if (len >= 3) {setCss(element, attr, value);return;}if (attr !== null && typeof attr === "object") {setGroupCss(element, attr);return;}return getCss(element, attr);};/** 获取元素距离BODY的偏移量*/const offset = function offset(element) {let parent = element.offsetParent,top = element.offsetTop,left = element.offsetLeft;while (parent) {if (!/MSIE 8/.test(navigator.userAgent)) {left += parent.clientLeft;top += parent.clientTop;}left += parent.offsetLeft;top += parent.offsetTop;parent = parent.offsetParent;}return {top,left};};/** 函数防抖处理*/const debounce = function debounce(func, wait, immediate) {if (typeof func !== "function") throw new TypeError('func must be an function');if (typeof wait === "boolean") {immediate = wait;wait = 300;}if (typeof wait !== "number") wait = 300;if (typeof immediate !== "boolean") immediate = false;let timer;return function proxy(...params) {let runNow = !timer && immediate,self = this,result;if (timer) {clearTimeout(timer);timer = null;}timer = setTimeout(() => {if (timer) {clearTimeout(timer);timer = null;}if (!immediate) result = func.call(self, ...params);}, wait);if (runNow) result = func.call(self, ...params);return result;};};/** 函数节流处理*/const throttle = function throttle(func, wait) {if (typeof func !== "function") throw new TypeError('func must be an function');if (typeof wait !== "number") wait = 300;let timer,previous = 0;return function proxy(...params) {let now = +new Date(),remaining = wait - (now - previous),self = this,result;if (remaining <= 0) {if (timer) {clearTimeout(timer);timer = null;}result = func.call(self, ...params);previous = now;} else if (!timer) {timer = setTimeout(() => {if (timer) {clearTimeout(timer);timer = null;}result = func.call(self, ...params);previous = +new Date();}, remaining);}return result;};};/* 暴露API */let utils = {debounce,throttle,offset,css,toType,isFunction,isWindow,isPlainObject,isArrayLike,isEmptyObject,isNumeric};let _$ = window.$;utils.noConflict = function noConflict() {if (window.$ === utils) window.$ = _$;return utils;};// 浏览器if(typeof window!=="undefined") window.util=window._=utils;// 支持 CommonJs规范if(typeof module==="object"&&typeof module.exports==="object") module.exports=utils;})();
