├── .babelrc ├── .browserslistrc ├── .gitignore ├── README.md ├── dev ├── index.html ├── index.js └── test.js ├── dist ├── utils.min.js └── utils.min.js.map ├── index.html ├── package.json ├── src ├── common │ └── index.js ├── cookie.js ├── encrypt │ ├── base64.js │ └── md5.js ├── explorer │ └── explorer.js ├── export.js ├── index.js ├── pattern │ └── observer.js ├── valid │ └── index.js └── worldCountry.js ├── webpack.config.js └── webpack.dev.config.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "@babel/preset-env" 5 | ] 6 | ], 7 | "plugins": ["@babel/plugin-proposal-export-default-from"] 8 | } 9 | -------------------------------------------------------------------------------- /.browserslistrc: -------------------------------------------------------------------------------- 1 | > 1% 2 | last 2 versions 3 | not ie <= 8 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | ### Node template 3 | # Logs 4 | logs 5 | *.log 6 | npm-debug.log* 7 | yarn-debug.log* 8 | yarn-error.log* 9 | 10 | # Runtime data 11 | pids 12 | *.pid 13 | *.seed 14 | *.pid.lock 15 | 16 | # Directory for instrumented libs generated by jscoverage/JSCover 17 | lib-cov 18 | 19 | # Coverage directory used by tools like istanbul 20 | coverage 21 | 22 | # nyc test coverage 23 | .nyc_output 24 | 25 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 26 | .grunt 27 | 28 | # Bower dependency directory (https://bower.io/) 29 | bower_components 30 | 31 | # node-waf configuration 32 | .lock-wscript 33 | 34 | # Compiled binary addons (https://nodejs.org/api/addons.html) 35 | build/Release 36 | 37 | # Dependency directories 38 | node_modules/ 39 | jspm_packages/ 40 | 41 | # TypeScript v1 declaration files 42 | typings/ 43 | 44 | # Optional npm cache directory 45 | .npm 46 | 47 | # Optional eslint cache 48 | .eslintcache 49 | 50 | # Optional REPL history 51 | .node_repl_history 52 | 53 | # Output of 'npm pack' 54 | *.tgz 55 | 56 | # Yarn Integrity file 57 | .yarn-integrity 58 | 59 | # dotenv environment variables file 60 | .env 61 | 62 | # parcel-bundler cache (https://parceljs.org/) 63 | .cache 64 | 65 | # IDE 66 | .idea 67 | 68 | # Service worker 69 | sw.* 70 | 71 | # logs 72 | npm-debug.log 73 | 74 | # Backpack build 75 | build 76 | 77 | #vscode config 78 | .vscode 79 | 80 | .git 81 | package-lock.json 82 | yarn.lock 83 | 84 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # js-utils 2 | 3 | > js常用工具类函数 4 | 5 | ### 使用方法 6 | 1.直接调用 7 | ```html 8 | 9 | 10 | ``` 11 | 2.import 调用 12 | 13 | npm install h-utils.js -D 14 | ```javascript 15 | import Utils from 'h-utils.js'; 16 | console.log(Utils.Common.getRandomNum(1,30)); 17 | ``` 18 | 19 | 3.require引用 20 | 21 | npm install h-utils.js -D 22 | ```javascript 23 | const Utils = require('h-utils.js'); 24 | console.log(Utils.Common.getRandomNum(1,30)); 25 | ``` 26 | 27 | 28 | ### Api 29 | #### Base64模块 30 | 1.Base64编码 31 | ```javascript 32 | Utils.Base64.encode("12"); 33 | ``` 34 | 35 | 2.Base64解码 36 | ```javascript 37 | Utils.Base64.decode("MTI=") 38 | ``` 39 | 40 | 41 | #### Md5模块 42 | md5加密 43 | ```javascript 44 | Utils.Md5("test"); 45 | ``` 46 | 47 | #### Common模块 48 | ``` 49 | 1.百度SEO 50 | 51 | Utils.Common.seo() 52 | 53 | 2.函数节流 节流函数fn 54 | 55 | Utils.Common.throttle(fn) 56 | 57 | 3.base64位码转blob对象 58 | 59 | @params dataurl - dataUrl 60 | 61 | Utils.Common.dataURLtoBlob(dataUrl) 62 | 63 | 4.获取n-m大小的随机整数 64 | 65 | Utils.Common.getRandomNum(1, 10); 66 | 67 | 5.将数字转成3位分隔符 68 | 69 | Utils.Common.splitNum(12003) // 12,000 70 | 71 | 6.字符串/数字数组去重 72 | 73 | Utils.Common.unique(["a", "a","b"]); // ["a","b"] 74 | 75 | 7.生成uuid 76 | 77 | Utils.Common.getUuid(); 78 | 79 | 8.过滤某字符串中的中文字符 80 | console.log(Utils.Common.filterChineseWord("我是js插件h-utils")); // jsh-utils 81 | 82 | 9.nodejs获取本地ip 83 | const os = require('os'); 84 | Utils.Common.getIPAddress(os); 85 | 86 | 10.获取元素实际样式值 87 | let dom = document.getElementById("demo"); 88 | Utils.Common.getStyle(dom, "height"); 89 | 90 | 11.获取display:none的元素的宽度高度等 91 | Utils.Common.getCurrentStyle(dom, "height") 92 | 93 | 12. * 实现jquery sildeToggle效果 94 | * @param el dom元素 95 | * @param time 动画时长,默认值300ms 96 | * @param fn 回调函数 97 | * @returns {boolean} 98 | Utils.Common.slideToggle( dom,300,function(){}) 99 | 100 | 13. * 实现jquery sildeUp效果 101 | * @param el dom元素 102 | * @param time 动画时长,默认值300ms 103 | * @param fn 回调函数 104 | * @returns {boolean} 105 | Utils.Common.slideUp( dom,300,function(){}) 106 | 107 | 14. * 实现jquery sildeDown效果 108 | * @param el dom元素 109 | * @param time 动画时长,默认值300ms 110 | * @param fn 回调函数 111 | * @returns {boolean} 112 | Utils.Common.sildeDown( dom,300,function(){}) 113 | 114 | 15.将base64/dataurl转成File 115 | 116 | @params dataurl - dataUrl, filename 117 | 118 | Utils.Common.dataURLtoFile(dataUrl, filename) 119 | 120 | 16.获取File 对象或 Blob 对象的临时路径 121 | 122 | @params file - File/Blob对象 123 | 124 | Utils.Common.getObjectURL(file) 125 | 126 | 17. /** 127 | * 获取当天的23:59:59的Date对象(当天最后1ms的Date对象) 128 | * @param date (默认值new Date()) 129 | * @returns {Date} 130 | */ 131 | 132 | var a = new Date(); 133 | Utils.Common.getDayLastMsDate(a); 134 | 135 | 18. /** 136 | * 获取当天的00:00的Date对象(当天最开始1ms的Date对象) 137 | * @param date (默认值new Date()) 138 | * @returns {Date} 139 | */ 140 | 141 | var a = new Date(); 142 | Utils.Common.getDayFirstMsDate(a); 143 | 144 | 19. 145 | /* 146 | 压缩图片 147 | dataUrl: dataUrl, 148 | obj:{ height, width, quality } 压缩之后的图片宽高,图片质量(0-1) 149 | type:压缩完之后的图片类型 150 | */ 151 | Utils.Common.photoCompress(dataUrl, { height:300,width:300,quality:1 },"image/png") 152 | 153 | 20.获取文件后缀格式名 154 | Utils.Common.getFileType("sabc.png"); // png 155 | 156 | 21.获取随机字符串 157 | Utils.Common.getRandomStr() 158 | 159 | 22.数组洗牌(重新随机排列) 160 | const arr = [1,2,3,4] 161 | Utils.Common.arrayShuffle(arr) 162 | 163 | ``` 164 | 165 | #### Common 表单校验模块 166 | ``` 167 | 1.大陆手机号判断 168 | 169 | Utils.Common.isPhone(15074956533) 170 | 171 | 2.全中文汉字校验 172 | 173 | Utils.Common.ChineseWordValid("中国") 174 | 175 | 3.英文和数字校验 176 | 177 | Utils.Common.wordNumValid("123sdd"); // true 178 | 179 | 4.emoji表情校验 180 | 181 | Utils.Common.emojiValid(params) 182 | 183 | 5.大陆身份证校验 184 | 185 | Utils.Common.IdentityCodeValid("430125455566556687") // false 186 | 187 | 6.邮箱校验 188 | Utils.Common.emailValid() 189 | ``` 190 | 191 | #### Country模块 -- 全世界国家和地区的英文名、中文名、英文简称、国家区号数组 192 | country未内置在Utils模块里,需要单独引入 193 | ```javascript 194 | import Country from 'h-utils.js/worldCountry' 195 | console.log(Country); 196 | ``` 197 | 198 | #### Explorer浏览器相关模块 199 | 1.从浏览器序列化get参数路径中获取参数 200 | 例子: 201 | ```javascript 202 | var str = "http://baidu.com?a=1&b=2" 203 | console.log(Utils.Explorer.getUrlParam("a")); // 1 204 | ``` 205 | 2.获取ie浏览器版本 206 | ```javascript 207 | Utils.Explorer.IEVersion(); 208 | ``` 209 | 210 | 3.浏览器滚动到底部时执行fn函数 211 | ```javascript 212 | window.addEventListener('scroll', ()=>{ 213 | Utils.Explorer.ScrollBottom(fn); 214 | }) 215 | window.addEventListener('touchmove', ()=>{ 216 | Utils.Explorer.ScrollBottom(fn); 217 | }) 218 | ``` 219 | 4.判断设备是否有网络权限 220 | ``` 221 | Utils.Explorer.validInternet(); // true 222 | ``` 223 | 224 | 225 | 4.判断手机浏览器版本 226 | ```javascript 227 | console.log(Utils.Explorer.explorerType()); 228 | ``` 229 | 230 | 返回参数说明: 231 | isAndroid: 是否为安卓环境 232 | isiOS:是否为ios环境 233 | isWeixin:是否为微信环境 234 | isQQ: 是否为qq环境 235 | 236 | 5.浏览器从底部减速缓慢滚动到顶部 237 | ```javascript 238 | Utils.Explorer.scrollToTop() 239 | ``` 240 | 241 | 242 | #### Cookie模块 243 | ```javascript 244 | Utils.Cookie.set('name', 'value', { expires: 365, path: '/' }); 245 | Utils.Cookie.get('name'); // => 'value' 246 | Utils.Cookie.remove('name'); 247 | ``` 248 | 249 | ### 设计模式 250 | #### 观察者模式(发布-订阅模式) 251 | ```javascript 252 | // 订阅消息 253 | Utils.Observer.subscribe('test', function (e) { 254 | console.log(e); 255 | }); 256 | // 发布消息 257 | Utils.Observer.publish('test', { 258 | msg: '参数' 259 | }); 260 | ``` 261 | 262 | 263 | -------------------------------------------------------------------------------- /dev/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | test h-utils.js 6 | 20 | 21 | 22 |
23 |

W3School - 领先的 Web 技术教程站点

24 |

在 W3School,你可以找到你所需要的所有网站建设教程。

25 |
26 | 27 |

请点击这里

28 | 29 | 30 | -------------------------------------------------------------------------------- /dev/index.js: -------------------------------------------------------------------------------- 1 | import Utils from "../dist/utils.min"; 2 | console.log(Utils.Observer); 3 | 4 | import { Common } from "../src/index"; 5 | console.log(Common) 6 | 7 | const Common1 = require("../dist/utils.min"); 8 | console.log(Common1) 9 | console.log(Common1.Md5); 10 | 11 | // 订阅消息 12 | 13 | Utils.Observer.subscribe('test', function (e) { 14 | console.log(e); 15 | }); 16 | // 发布消息 17 | Utils.Observer.publish('test', { 18 | msg: '参数' 19 | }); 20 | 21 | document.getElementById("point").onclick = ()=>{ 22 | Utils.Common.slideToggle(document.getElementById("elem"), 300); 23 | } 24 | -------------------------------------------------------------------------------- /dev/test.js: -------------------------------------------------------------------------------- 1 | const utils = require("h-utils.js"); 2 | 3 | console.log(utils.Common.getIPAdress()); -------------------------------------------------------------------------------- /dist/utils.min.js: -------------------------------------------------------------------------------- 1 | !function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.Utils=e():t.Utils=e()}(this,(function(){return n={},t.m=e=[function(t,e,n){"use strict";n.r(e),n.d(e,"Base64",(function(){return r})),n.d(e,"Md5",(function(){return o})),n.d(e,"Common",(function(){return h})),n.d(e,"Valid",(function(){return w})),n.d(e,"Explorer",(function(){return b})),n.d(e,"Cookie",(function(){return S})),n.d(e,"Observer",(function(){return A}));var r={_keyStr:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",encode:function(t){var e,n,o,i,a,u,d,l="",c=0;for(t=r._utf8_encode(t);c>2,a=(3&e)<<4|(n=t.charCodeAt(c++))>>4,u=(15&n)<<2|(o=t.charCodeAt(c++))>>6,d=63&o,isNaN(n)?u=d=64:isNaN(o)&&(d=64),l=l+this._keyStr.charAt(i)+this._keyStr.charAt(a)+this._keyStr.charAt(u)+this._keyStr.charAt(d);return l},decode:function(t){var e,n,o,i,a,u,d="",l=0;for(t=t.replace(/[^A-Za-z0-9+/=]/g,"");l>4,n=(15&i)<<4|(a=this._keyStr.indexOf(t.charAt(l++)))>>2,o=(3&a)<<6|(u=this._keyStr.indexOf(t.charAt(l++))),d+=String.fromCharCode(e),64!=a&&(d+=String.fromCharCode(n)),64!=u&&(d+=String.fromCharCode(o));return r._utf8_decode(d)},_utf8_encode:function(t){t=t.replace(/rn/g,"n");for(var e="",n=0;n>6|192):(e+=String.fromCharCode(r>>12|224),e+=String.fromCharCode(r>>6&63|128)),e+=String.fromCharCode(63&r|128))}return e},_utf8_decode:function(t){for(var e="",n=0,r=c1=c2=0;n>>32-e}function n(t,e){var n=2147483648&t,r=2147483648&e,o=1073741824&t,i=1073741824&e,a=(1073741823&t)+(1073741823&e);return o&i?2147483648^a^n^r:o|i?1073741824&a?3221225472^a^n^r:1073741824^a^n^r:a^n^r}function r(t,r,o,i,a,u,d){var l;return t=n(t,n(n((l=r)&o|~l&i,a),d)),n(e(t,u),r)}function o(t,r,o,i,a,u,d){var l;return t=n(t,n(n(r&(l=i)|o&~l,a),d)),n(e(t,u),r)}function i(t,r,o,i,a,u,d){return t=n(t,n(n(r^o^i,a),d)),n(e(t,u),r)}function a(t,r,o,i,a,u,d){return t=n(t,n(n(o^(r|~i),a),d)),n(e(t,u),r)}function u(t){for(var e="",n="",r=0;r<=3;r++)e+=(n="0"+(t>>>8*r&255).toString(16)).substr(n.length-2,2);return e}for(var d,l,c,s,f=Array(),h=(f=function(t){for(var e,n=t.length,r=n+8,o=16*(1+(r-r%64)/64),i=Array(o-1),a=0,u=0;u>>29,i}(t=function(t){t=t.replace(/\r\n/g,"\n");for(var e="",n=0;n>6|192):(e+=String.fromCharCode(r>>12|224),e+=String.fromCharCode(r>>6&63|128)),e+=String.fromCharCode(63&r|128))}return e}(t)),1732584193),m=4023233417,g=2562383102,p=271733878,y=0;y=e.height&&(o=e.height),t=o*i;var a=1,u=document.createElement("canvas"),d=u.getContext("2d"),l=document.createAttribute("width");l.nodeValue=t;var c=document.createAttribute("height");c.nodeValue=o,u.setAttributeNode(l),u.setAttributeNode(c),d.drawImage(this,0,0,t,o),e.quality&&e.quality<=1&&0> 2;\n o = (n & 3) << 4 | r >> 4;\n u = (r & 15) << 2 | i >> 6;\n a = i & 63;\n if (isNaN(r)) {\n u = a = 64\n } else if (isNaN(i)) {\n a = 64\n }\n t = t + this._keyStr.charAt(s) + this._keyStr.charAt(o) + this._keyStr.charAt(u) + this._keyStr.charAt(a)\n }\n return t\n },\n decode: function(e) {\n let t = \"\";\n let n, r, i;\n let s, o, u, a;\n let f = 0;\n e=e.replace(/[^A-Za-z0-9+/=]/g,\"\");\n while (f < e.length) {\n s = this._keyStr.indexOf(e.charAt(f++));\n o = this._keyStr.indexOf(e.charAt(f++));\n u = this._keyStr.indexOf(e.charAt(f++));\n a = this._keyStr.indexOf(e.charAt(f++));\n n = s << 2 | o >> 4;\n r = (o & 15) << 4 | u >> 2;\n i = (u & 3) << 6 | a;\n t = t + String.fromCharCode(n);\n if (u != 64) {\n t = t + String.fromCharCode(r)\n }\n if (a != 64) {\n t = t + String.fromCharCode(i)\n }\n }\n t = Base64._utf8_decode(t);\n return t\n },\n _utf8_encode: function(e) {\n e = e.replace(/rn/g, \"n\");\n let t = \"\";\n for (let n = 0; n < e.length; n++) {\n let r = e.charCodeAt(n);\n if (r < 128) {\n t += String.fromCharCode(r)\n } else if (r > 127 && r < 2048) {\n t += String.fromCharCode(r >> 6 | 192);\n t += String.fromCharCode(r & 63 | 128)\n } else {\n t += String.fromCharCode(r >> 12 | 224);\n t += String.fromCharCode(r >> 6 & 63 | 128);\n t += String.fromCharCode(r & 63 | 128)\n }\n }\n return t\n },\n _utf8_decode: function(e) {\n let t = \"\";\n let n = 0;\n let r = c1 = c2 = 0;\n while (n < e.length) {\n r = e.charCodeAt(n);\n if (r < 128) {\n t += String.fromCharCode(r);\n n++\n } else if (r > 191 && r < 224) {\n c2 = e.charCodeAt(n + 1);\n t += String.fromCharCode((r & 31) << 6 | c2 & 63);\n n += 2\n } else {\n c2 = e.charCodeAt(n + 1);\n c3 = e.charCodeAt(n + 2);\n t += String.fromCharCode((r & 15) << 12 | (c2 & 63) << 6 | c3 & 63);\n n += 3\n }\n }\n return t\n }\n};\n\nexport default Base64;\n","export const Md5 = function(string) {\n function md5_RotateLeft(lValue, iShiftBits) {\n return (lValue << iShiftBits) | (lValue >>> (32 - iShiftBits));\n }\n function md5_AddUnsigned(lX, lY) {\n var lX4, lY4, lX8, lY8, lResult;\n lX8 = (lX & 0x80000000);\n lY8 = (lY & 0x80000000);\n lX4 = (lX & 0x40000000);\n lY4 = (lY & 0x40000000);\n lResult = (lX & 0x3FFFFFFF) + (lY & 0x3FFFFFFF);\n if (lX4 & lY4) {\n return (lResult ^ 0x80000000 ^ lX8 ^ lY8);\n }\n if (lX4 | lY4) {\n if (lResult & 0x40000000) {\n return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);\n } else {\n return (lResult ^ 0x40000000 ^ lX8 ^ lY8);\n }\n } else {\n return (lResult ^ lX8 ^ lY8);\n }\n }\n function md5_F(x, y, z) {\n return (x & y) | ((~x) & z);\n }\n function md5_G(x, y, z) {\n return (x & z) | (y & (~z));\n }\n function md5_H(x, y, z) {\n return (x ^ y ^ z);\n }\n function md5_I(x, y, z) {\n return (y ^ (x | (~z)));\n }\n function md5_FF(a, b, c, d, x, s, ac) {\n a = md5_AddUnsigned(a, md5_AddUnsigned(md5_AddUnsigned(md5_F(b, c, d), x), ac));\n return md5_AddUnsigned(md5_RotateLeft(a, s), b);\n };\n function md5_GG(a, b, c, d, x, s, ac) {\n a = md5_AddUnsigned(a, md5_AddUnsigned(md5_AddUnsigned(md5_G(b, c, d), x), ac));\n return md5_AddUnsigned(md5_RotateLeft(a, s), b);\n };\n function md5_HH(a, b, c, d, x, s, ac) {\n a = md5_AddUnsigned(a, md5_AddUnsigned(md5_AddUnsigned(md5_H(b, c, d), x), ac));\n return md5_AddUnsigned(md5_RotateLeft(a, s), b);\n };\n function md5_II(a, b, c, d, x, s, ac) {\n a = md5_AddUnsigned(a, md5_AddUnsigned(md5_AddUnsigned(md5_I(b, c, d), x), ac));\n return md5_AddUnsigned(md5_RotateLeft(a, s), b);\n };\n function md5_ConvertToWordArray(string) {\n var lWordCount;\n var lMessageLength = string.length;\n var lNumberOfWords_temp1 = lMessageLength + 8;\n var lNumberOfWords_temp2 = (lNumberOfWords_temp1 - (lNumberOfWords_temp1 % 64)) / 64;\n var lNumberOfWords = (lNumberOfWords_temp2 + 1) * 16;\n var lWordArray = Array(lNumberOfWords - 1);\n var lBytePosition = 0;\n var lByteCount = 0;\n while (lByteCount < lMessageLength) {\n lWordCount = (lByteCount - (lByteCount % 4)) / 4;\n lBytePosition = (lByteCount % 4) * 8;\n lWordArray[lWordCount] = (lWordArray[lWordCount] | (string.charCodeAt(lByteCount) << lBytePosition));\n lByteCount++;\n }\n lWordCount = (lByteCount - (lByteCount % 4)) / 4;\n lBytePosition = (lByteCount % 4) * 8;\n lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80 << lBytePosition);\n lWordArray[lNumberOfWords - 2] = lMessageLength << 3;\n lWordArray[lNumberOfWords - 1] = lMessageLength >>> 29;\n return lWordArray;\n };\n function md5_WordToHex(lValue) {\n var WordToHexValue = \"\",\n WordToHexValue_temp = \"\",\n lByte, lCount;\n for (lCount = 0; lCount <= 3; lCount++) {\n lByte = (lValue >>> (lCount * 8)) & 255;\n WordToHexValue_temp = \"0\" + lByte.toString(16);\n WordToHexValue = WordToHexValue + WordToHexValue_temp.substr(WordToHexValue_temp.length - 2, 2);\n }\n return WordToHexValue;\n };\n function md5_Utf8Encode(string) {\n string = string.replace(/\\r\\n/g, \"\\n\");\n var utftext = \"\";\n for (var n = 0; n < string.length; n++) {\n var c = string.charCodeAt(n);\n if (c < 128) {\n utftext += String.fromCharCode(c);\n } else if ((c > 127) && (c < 2048)) {\n utftext += String.fromCharCode((c >> 6) | 192);\n utftext += String.fromCharCode((c & 63) | 128);\n } else {\n utftext += String.fromCharCode((c >> 12) | 224);\n utftext += String.fromCharCode(((c >> 6) & 63) | 128);\n utftext += String.fromCharCode((c & 63) | 128);\n }\n }\n return utftext;\n };\n var x = Array();\n var k, AA, BB, CC, DD, a, b, c, d;\n var S11 = 7,\n S12 = 12,\n S13 = 17,\n S14 = 22;\n var S21 = 5,\n S22 = 9,\n S23 = 14,\n S24 = 20;\n var S31 = 4,\n S32 = 11,\n S33 = 16,\n S34 = 23;\n var S41 = 6,\n S42 = 10,\n S43 = 15,\n S44 = 21;\n string = md5_Utf8Encode(string);\n x = md5_ConvertToWordArray(string);\n a = 0x67452301;\n b = 0xEFCDAB89;\n c = 0x98BADCFE;\n d = 0x10325476;\n for (k = 0; k < x.length; k += 16) {\n AA = a;\n BB = b;\n CC = c;\n DD = d;\n a = md5_FF(a, b, c, d, x[k + 0], S11, 0xD76AA478);\n d = md5_FF(d, a, b, c, x[k + 1], S12, 0xE8C7B756);\n c = md5_FF(c, d, a, b, x[k + 2], S13, 0x242070DB);\n b = md5_FF(b, c, d, a, x[k + 3], S14, 0xC1BDCEEE);\n a = md5_FF(a, b, c, d, x[k + 4], S11, 0xF57C0FAF);\n d = md5_FF(d, a, b, c, x[k + 5], S12, 0x4787C62A);\n c = md5_FF(c, d, a, b, x[k + 6], S13, 0xA8304613);\n b = md5_FF(b, c, d, a, x[k + 7], S14, 0xFD469501);\n a = md5_FF(a, b, c, d, x[k + 8], S11, 0x698098D8);\n d = md5_FF(d, a, b, c, x[k + 9], S12, 0x8B44F7AF);\n c = md5_FF(c, d, a, b, x[k + 10], S13, 0xFFFF5BB1);\n b = md5_FF(b, c, d, a, x[k + 11], S14, 0x895CD7BE);\n a = md5_FF(a, b, c, d, x[k + 12], S11, 0x6B901122);\n d = md5_FF(d, a, b, c, x[k + 13], S12, 0xFD987193);\n c = md5_FF(c, d, a, b, x[k + 14], S13, 0xA679438E);\n b = md5_FF(b, c, d, a, x[k + 15], S14, 0x49B40821);\n a = md5_GG(a, b, c, d, x[k + 1], S21, 0xF61E2562);\n d = md5_GG(d, a, b, c, x[k + 6], S22, 0xC040B340);\n c = md5_GG(c, d, a, b, x[k + 11], S23, 0x265E5A51);\n b = md5_GG(b, c, d, a, x[k + 0], S24, 0xE9B6C7AA);\n a = md5_GG(a, b, c, d, x[k + 5], S21, 0xD62F105D);\n d = md5_GG(d, a, b, c, x[k + 10], S22, 0x2441453);\n c = md5_GG(c, d, a, b, x[k + 15], S23, 0xD8A1E681);\n b = md5_GG(b, c, d, a, x[k + 4], S24, 0xE7D3FBC8);\n a = md5_GG(a, b, c, d, x[k + 9], S21, 0x21E1CDE6);\n d = md5_GG(d, a, b, c, x[k + 14], S22, 0xC33707D6);\n c = md5_GG(c, d, a, b, x[k + 3], S23, 0xF4D50D87);\n b = md5_GG(b, c, d, a, x[k + 8], S24, 0x455A14ED);\n a = md5_GG(a, b, c, d, x[k + 13], S21, 0xA9E3E905);\n d = md5_GG(d, a, b, c, x[k + 2], S22, 0xFCEFA3F8);\n c = md5_GG(c, d, a, b, x[k + 7], S23, 0x676F02D9);\n b = md5_GG(b, c, d, a, x[k + 12], S24, 0x8D2A4C8A);\n a = md5_HH(a, b, c, d, x[k + 5], S31, 0xFFFA3942);\n d = md5_HH(d, a, b, c, x[k + 8], S32, 0x8771F681);\n c = md5_HH(c, d, a, b, x[k + 11], S33, 0x6D9D6122);\n b = md5_HH(b, c, d, a, x[k + 14], S34, 0xFDE5380C);\n a = md5_HH(a, b, c, d, x[k + 1], S31, 0xA4BEEA44);\n d = md5_HH(d, a, b, c, x[k + 4], S32, 0x4BDECFA9);\n c = md5_HH(c, d, a, b, x[k + 7], S33, 0xF6BB4B60);\n b = md5_HH(b, c, d, a, x[k + 10], S34, 0xBEBFBC70);\n a = md5_HH(a, b, c, d, x[k + 13], S31, 0x289B7EC6);\n d = md5_HH(d, a, b, c, x[k + 0], S32, 0xEAA127FA);\n c = md5_HH(c, d, a, b, x[k + 3], S33, 0xD4EF3085);\n b = md5_HH(b, c, d, a, x[k + 6], S34, 0x4881D05);\n a = md5_HH(a, b, c, d, x[k + 9], S31, 0xD9D4D039);\n d = md5_HH(d, a, b, c, x[k + 12], S32, 0xE6DB99E5);\n c = md5_HH(c, d, a, b, x[k + 15], S33, 0x1FA27CF8);\n b = md5_HH(b, c, d, a, x[k + 2], S34, 0xC4AC5665);\n a = md5_II(a, b, c, d, x[k + 0], S41, 0xF4292244);\n d = md5_II(d, a, b, c, x[k + 7], S42, 0x432AFF97);\n c = md5_II(c, d, a, b, x[k + 14], S43, 0xAB9423A7);\n b = md5_II(b, c, d, a, x[k + 5], S44, 0xFC93A039);\n a = md5_II(a, b, c, d, x[k + 12], S41, 0x655B59C3);\n d = md5_II(d, a, b, c, x[k + 3], S42, 0x8F0CCC92);\n c = md5_II(c, d, a, b, x[k + 10], S43, 0xFFEFF47D);\n b = md5_II(b, c, d, a, x[k + 1], S44, 0x85845DD1);\n a = md5_II(a, b, c, d, x[k + 8], S41, 0x6FA87E4F);\n d = md5_II(d, a, b, c, x[k + 15], S42, 0xFE2CE6E0);\n c = md5_II(c, d, a, b, x[k + 6], S43, 0xA3014314);\n b = md5_II(b, c, d, a, x[k + 13], S44, 0x4E0811A1);\n a = md5_II(a, b, c, d, x[k + 4], S41, 0xF7537E82);\n d = md5_II(d, a, b, c, x[k + 11], S42, 0xBD3AF235);\n c = md5_II(c, d, a, b, x[k + 2], S43, 0x2AD7D2BB);\n b = md5_II(b, c, d, a, x[k + 9], S44, 0xEB86D391);\n a = md5_AddUnsigned(a, AA);\n b = md5_AddUnsigned(b, BB);\n c = md5_AddUnsigned(c, CC);\n d = md5_AddUnsigned(d, DD);\n }\n return (md5_WordToHex(a) + md5_WordToHex(b) + md5_WordToHex(c) + md5_WordToHex(d)).toLowerCase();\n}\n\nexport default Md5;","// 百度SEO\nconst seo = function() {\n let bp = document.createElement('script');\n let curProtocol = window.location.protocol.split(':')[0];\n if (curProtocol === 'https') {\n bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';\n }\n else {\n bp.src = 'http://push.zhanzhang.baidu.com/push.js';\n }\n let s = document.getElementsByTagName(\"script\")[0];\n s.parentNode.insertBefore(bp, s);\n};\n\n// 函数节流\nconst throttle = function(method, context) {\n clearTimeout(method.tId);\n method.tId = setTimeout(function () {\n method.call(context);\n }.bind(this), context?context:1000);\n};\n\n// base64位码转blob对象\nconst dataURLtoBlob = (dataurl)=>{\n let arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],\n bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);\n while(n--){\n u8arr[n] = bstr.charCodeAt(n);\n }\n return new Blob([u8arr], {type:mime});\n};\n\n// 生成随机字符串\nfunction getRandomStr(){\n return Math.random().toString(36).substring(2)\n}\n\n/**\n * 将base64/dataurl转成File\n * @param dataurl\n * @param filename\n * @returns {File}\n */\nfunction dataURLtoFile(dataurl, filename) {\n let arr = dataurl.split(','),\n mime = arr[0].match(/:(.*?);/)[1],\n bstr = atob(arr[1]),\n n = bstr.length,\n u8arr = new Uint8Array(n);\n while (n--) {\n u8arr[n] = bstr.charCodeAt(n);\n }\n return new File([u8arr], filename, { type: mime });\n}\n\n// 获取File 对象或 Blob 对象的临时路径\nfunction getObjectURL(file) {\n let url = null;\n if (window.createObjectURL) {\n // basic\n url = window.createObjectURL(file);\n } else if (window.URL) {\n // mozilla(firefox)\n url = window.URL.createObjectURL(file);\n } else if (window.webkitURL) {\n // webkit or chrome\n url = window.webkitURL.createObjectURL(file);\n }\n return url;\n}\n\n// 获取n-m的随机整数\nconst getRandomNum = (n, m)=> {\n return Math.ceil(Math.random()*(m-n), n);\n};\n\n// 将数字转成3位分隔符\nconst splitNum = function (num) {\n if (num === null || num === undefined) {\n return null;\n }\n if (typeof num === \"number\") {\n num = num.toString()\n }\n return num.replace(/\\B(?=(?:\\d{3})+\\b)/g, ',')\n};\n\n// 字符串/数字数组去重\nfunction unique(arr) {\n return Array.from(new Set(arr));\n}\n\n// 生成uuid\nfunction getUuid() {\n let s = [];\n let hexDigits = \"0123456789abcdef\";\n for (let i = 0; i < 36; i++) {\n s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);\n }\n s[14] = \"4\"; // bits 12-15 of the time_hi_and_version field to 0010\n s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01\n s[8] = s[13] = s[18] = s[23] = \"-\";\n\n return s.join(\"\");\n}\n\n// 过滤掉某个字符串中的中文字符\nfunction filterChineseWord(str) {\n return str.replace(/[\\u4E00-\\u9FA5]/g, '');\n}\n\n/**\n * nodejs获取本地ip\n * @param os node.js os模块\n * @returns {*}\n */\nfunction getIPAddress(os) {\n if (!os) return '';\n let interfaces = os.networkInterfaces();\n for (let devName in interfaces) {\n let iface = interfaces[devName];\n for (let i = 0; i < iface.length; i++) {\n let alias = iface[i];\n if (alias.family === 'IPv4' && alias.address !== '127.0.0.1' && !alias.internal) {\n return alias.address;\n }\n }\n }\n}\n\n/**\n * 获取元素实际样式值\n * @param el dom元素\n * @param styleName 样式名\n */\nfunction getStyle(el, styleName) {\n if (el.currentStyle) return el.currentStyle[styleName];\n if (getComputedStyle) return window.getComputedStyle(el, null)[styleName];\n return el.style[styleName];\n}\n\n// 优雅降级requestAnimationFrame\nconst requestAnimationF = (function () {\n return window.requestAnimationFrame ||\n window.webkitRequestAnimationFrame ||\n window.mozRequestAnimationFrame ||\n window.oRequestAnimationFrame ||\n // if all else fails, use setTimeout\n function (callback) {\n return window.setTimeout(callback, 1000 / 60); // shoot for 60 fps\n };\n})();\n\n// 优雅降级cancelAnimationFrame\nconst cancelAnimationF = (function () {\n return window.cancelAnimationFrame ||\n window.webkitCancelAnimationFrame ||\n window.mozCancelAnimationFrame ||\n window.oCancelAnimationFrame ||\n function (id) {\n window.clearTimeout(id);\n };\n})();\n\n\n/**\n * 获取元素实际高度\n * @param el dom元素\n * @returns {number} 元素高度\n */\nfunction getHeight(el) {\n let height;\n // 已隐藏的元素\n if (getStyle(el, \"display\") === \"none\") {\n el.style.position = \"absolute\";\n el.style.visibility = \"hidden\";\n el.style.display = \"block\";\n height = getStyle(el, \"height\");\n el.style.position = \"\";\n el.style.visibility = \"\";\n el.style.display = \"\";\n return parseFloat(height);\n }\n return parseFloat(getStyle(el, \"height\"));\n}\n\n/**\n * 获取已隐藏元素的css值\n * @param el\n * @param styleName\n * @returns {*}\n */\nfunction getCurrentStyle(el, styleName) {\n let styleValue;\n // 已隐藏的元素\n if (getStyle(el, \"display\") === \"none\") {\n el.style.position = \"absolute\";\n el.style.visibility = \"hidden\";\n el.style.display = \"block\";\n styleValue = getStyle(el, styleName);\n el.style.position = \"\";\n el.style.visibility = \"\";\n el.style.display = \"\";\n return (styleValue);\n }\n return (getStyle(el, styleName));\n}\n\n/**\n * 优化实现sildeToggle效果\n * @param el dom元素\n * @param time 动画时长,单位ms,默认值300\n * @param fn 回调函数\n */\nfunction slideToggle(el, time, fn) {\n if (!el) return false;\n time = time || 300;\n if (el.dataUid) return false; // 如该dom元素已有动画未处理完,则必须等到动画结束才执行\n\n cancelAnimationF(el.dataUid);\n\n // 已隐藏的元素,下拉\n if (getStyle(el, \"display\") === \"none\" || getHeight(el) === 0) {\n down(el, time, fn);\n } else {\n up(el, time, fn)\n }\n}\n\nfunction down(el, time, fn) {\n let aniSplitTime = Date.now();\n\n let height = 0, paddingTop = 0, paddingBottom = 0;\n let totalHeight = parseFloat(getCurrentStyle(el, \"height\"));\n let totalPaddingTop = parseFloat(getCurrentStyle(el, \"paddingTop\"));\n let totalPaddingBottom = parseFloat(getCurrentStyle(el, \"paddingBottom\"));\n\n let basePaddingBottom = totalPaddingBottom/time;\n let basePaddingTop = totalPaddingBottom/time;\n let baseHeight = totalHeight/time;\n\n el.style.overflow = \"hidden\";\n el.style.display = \"block\";\n\n el.dataUid = requestAnimationF(function go(){\n let aniTime = Date.now();\n let splitTime = aniTime - aniSplitTime;\n aniSplitTime = aniTime;\n let splitPaddingBottom = basePaddingBottom*splitTime;\n let splitPaddingTop = basePaddingTop*splitTime;\n let splitHeight = baseHeight*splitTime;\n\n if (height >= totalHeight){\n el.style.overflow = \"\";\n el.style.height = \"\";\n el.style.paddingTop = \"\";\n el.style.paddingBottom = \"\";\n\n if (fn && typeof fn === \"function\") fn();\n cancelAnimationF(el.dataUid);\n el.dataUid = null;\n delete el.dataUid;\n } else {\n el.style.height = height + \"px\";\n el.style.paddingTop = paddingTop + \"px\";\n el.style.paddingBottom = paddingBottom + \"px\";\n el.dataUid = requestAnimationF(go);\n }\n height = height + splitHeight;\n paddingTop = paddingTop + splitPaddingTop;\n paddingBottom = paddingBottom + splitPaddingBottom;\n });\n}\n\nfunction up(el, time, fn) {\n // 上拉\n let aniSplitTime = Date.now();\n let height = getHeight(el);\n let paddingTop = parseFloat(getStyle(el, \"paddingTop\"));\n let paddingBottom = parseFloat(getStyle(el, \"paddingBottom\"));\n el.style.overflow = \"hidden\";\n\n let basePaddingBottom = paddingBottom/time;\n let basePaddingTop = paddingTop/time;\n let baseHeight = height/time;\n\n el.dataUid = requestAnimationF(function go(){\n let aniTime = Date.now();\n let splitTime = aniTime - aniSplitTime;\n aniSplitTime = aniTime;\n let splitPaddingBottom = basePaddingBottom*splitTime;\n let splitPaddingTop = basePaddingTop*splitTime;\n let splitHeight = baseHeight*splitTime;\n\n if (height <= 0) {\n el.style.height = 0;\n el.style.paddingTop = 0;\n el.style.paddingBottom = 0;\n\n setTimeout(()=>{\n el.style.height = \"\";\n el.style.overflow = \"\";\n el.style.paddingTop = \"\";\n el.style.paddingBottom = \"\";\n el.style.display = \"none\";\n },0);\n\n if (fn && typeof fn === \"function\") fn();\n cancelAnimationF(el.dataUid);\n el.dataUid = null;\n delete el.dataUid;\n } else {\n el.style.height = height + \"px\";\n el.style.paddingTop = paddingTop + \"px\";\n el.style.paddingBottom = paddingBottom + \"px\";\n el.dataUid = requestAnimationF(go);\n }\n\n height = height - splitHeight;\n paddingBottom = paddingBottom - splitPaddingBottom;\n paddingTop = paddingTop - splitPaddingTop;\n });\n}\n\n/**\n * 优化实现jquery slideDown效果\n * @param el dom元素\n * @param time 动画时长,单位ms,默认值300\n * @param fn 回调函数\n */\nfunction slideDown(el, time, fn) {\n if (!el) return false;\n time = time || 300;\n if (el.dataUid) return false; // 如该dom元素已有动画未处理完,则必须等到动画结束才执行\n\n cancelAnimationF(el.dataUid);\n if (getStyle(el, \"display\") === \"none\" || getHeight(el) === 0) {\n down(el, time, fn);\n }\n}\n\n/**\n * 优化实现jquery slideUp效果\n * @param el dom元素\n * @param time 动画时长,单位ms,默认值300\n * @param fn 回调函数\n */\nfunction slideUp(el, time, fn) {\n if (!el) return false;\n time = time || 300;\n if (el.dataUid) return false; // 如该dom元素已有动画未处理完,则必须等到动画结束才执行\n\n cancelAnimationF(el.dataUid);\n\n if (getStyle(el, \"display\") === \"none\" || getHeight(el) === 0) {\n\n } else {\n up(el, time, fn);\n }\n}\n\n/**\n * 获取当天的23:59:59的Date对象(当天最后1ms的Date对象)\n * @param date (默认值new Date())\n * @returns {Date}\n */\nfunction getDayLastMsDate(date = new Date()) {\n if (!date instanceof Date) {\n throw new Error(\"function params type error\");\n }\n return new Date(new Date(date.toLocaleDateString()).getTime()+24*60*60*1000-1)\n}\n\n/**\n * 获取当天的00:00的Date对象(当天最开始1ms的Date对象)\n * @param date (默认值new Date())\n * @returns {Date}\n */\nfunction getDayFirstMsDate(date = new Date()) {\n if (!date instanceof Date) {\n throw new Error(\"function params type error\");\n }\n return new Date(date.toLocaleDateString())\n}\n\n/*\n 压缩图片\n dataUrl: dataUrl,\n obj:{ height, width } 压缩之后的图片宽高\n type:压缩完之后的图片类型\n*/\nfunction photoCompress(dataUrl, obj, type = \"image/png\"){\n return new Promise((resolve, reject) => {\n let img = new Image();\n img.src = dataUrl;\n img.onload = function(){\n let that = this;\n // 默认按比例压缩\n let w = that.width,\n h = that.height,\n scale = w / h;\n if (h >= obj.height) {\n h = obj.height;\n }\n w = (h * scale);\n\n let quality = 1; // 默认图片质量为1\n //生成canvas\n let canvas = document.createElement('canvas');\n let ctx = canvas.getContext('2d');\n // 创建属性节点\n let anw = document.createAttribute(\"width\");\n anw.nodeValue = w;\n let anh = document.createAttribute(\"height\");\n anh.nodeValue = h;\n canvas.setAttributeNode(anw);\n canvas.setAttributeNode(anh);\n ctx.drawImage(that, 0, 0, w, h);\n // 图像质量\n if(obj.quality && obj.quality <= 1 && obj.quality > 0){\n quality = obj.quality;\n }\n // quality值越小,所绘制出的图像越模糊\n let base64 = canvas.toDataURL(type, quality);\n // 回调函数返回base64的值\n resolve(base64);\n };\n img.onerror = ()=>{\n reject();\n }\n })\n\n}\n\n// 获取文件格式(后缀)\nfunction getFileType(fileName = '') {\n let index = fileName.lastIndexOf(\".\");\n if (index >= 0) return fileName.substring(index + 1);\n return \"\";\n}\n\nexport const Common = {\n seo,\n throttle,\n dataURLtoBlob,\n getRandomNum,\n splitNum,\n getUuid,\n getRandomStr,\n unique,\n filterChineseWord,\n getIPAddress,\n getStyle,\n getCurrentStyle,\n slideToggle,\n slideUp,\n slideDown,\n getObjectURL,\n dataURLtoFile,\n getDayLastMsDate,\n getDayFirstMsDate,\n photoCompress,\n getFileType\n};\n\nexport default Common;\n\n\n","// 大陆手机号判断\nconst isPhone = (val)=>{\n return /^1[3456789]\\d{9}$/.test(val);\n};\n\n/*\n* 全中文校验\n* */\nfunction ChineseWordValid (val) {\n return /^[\\u4E00-\\u9FA5]+$/.test(val);\n}\n\n// 英文和数字校验\nfunction wordNumValid(val) {\n return /^[0-9A-Za-z]+$/.test(val);\n}\n\n// emoji表情校验\nfunction emojiValid(val) {\n const regStr = /[\\uD83C|\\uD83D|\\uD83E][\\uDC00-\\uDFFF][\\u200D|\\uFE0F]|[\\uD83C|\\uD83D|\\uD83E][\\uDC00-\\uDFFF]|[0-9|*|#]\\uFE0F\\u20E3|[0-9|#]\\u20E3|[\\u203C-\\u3299]\\uFE0F\\u200D|[\\u203C-\\u3299]\\uFE0F|[\\u2122-\\u2B55]|\\u303D|[\\A9|\\AE]\\u3030|\\uA9|\\uAE|\\u3030/ig;\n return (regStr.test(val))\n}\n\n// 邮箱校验\nfunction emailValid (val) {\n return /^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$/.test(val);\n}\n\n/*\n* 大陆身份证校验\n* */\nconst IdentityCodeValid = function (code) {\n let city = {\n 11:\"北京\",12:\"天津\",13:\"河北\",14:\"山西\",15:\"内蒙古\",21:\"辽宁\",22:\"吉林\",23:\"黑龙江 \",31:\"上海\",32:\"江苏\",\n 33:\"浙江\",34:\"安徽\",35:\"福建\",36:\"江西\",37:\"山东\",41:\"河南\",42:\"湖北 \",43:\"湖南\",44:\"广东\",45:\"广西\",46:\"海南\",\n 50:\"重庆\",51:\"四川\",52:\"贵州\",53:\"云南\",54:\"西藏 \",61:\"陕西\",62:\"甘肃\",63:\"青海\",64:\"宁夏\",65:\"新疆\",\n 71:\"台湾\",81:\"香港\",82:\"澳门\",91:\"国外 \"\n };\n let tip = '';\n let pass = true;\n\n if(!code || !/^\\d{6}(18|19|20)?\\d{2}(0[1-9]|1[012])(0[1-9]|[12]\\d|3[01])\\d{3}(\\d|X)$/i.test(code)){\n tip = \"身份证号格式错误\";\n pass = false\n } else if(!city[code.substr(0,2)]){\n tip = \"地址编码错误\";\n pass = false\n } else{\n // 18位身份证需要验证最后一位校验位\n if(code.length == 18){\n code = code.split('')\n // ∑(ai×Wi)(mod 11)\n // 加权因子\n let factor = [ 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 ]\n // 校验位\n let parity = [ 1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2 ]\n let sum = 0\n let ai = 0\n let wi = 0\n for (let i = 0; i < 17; i++)\n {\n ai = code[i]\n wi = factor[i]\n sum += ai * wi\n }\n let last = parity[sum % 11];\n if(parity[sum % 11] != code[17]){\n tip = \"校验位错误\"\n pass = false;\n }\n }\n }\n return pass;\n};\n\nexport const Valid = {\n isPhone, ChineseWordValid, wordNumValid, emojiValid, IdentityCodeValid\n};\n\nexport default {\n isPhone, ChineseWordValid, wordNumValid, emojiValid, IdentityCodeValid\n}","/*\n* 发布-订阅模式(观察者模式)\n* */\n\nexport const Observer = (function () {\n let messages = {}; // 消息队列\n\n return {\n // 订阅消息\n subscribe (type, fn) {\n // 消息不存在,创建消息执行队列\n if (typeof messages[type] === 'undefined') {\n messages[type] = [fn];\n }\n // 消息存在,将执行动作推进消息执行队列\n else {\n messages[type].push(fn);\n }\n },\n // 发布消息\n publish (type, args) {\n // 如果消息未被注册,返回false\n if (!messages[type]) return false;\n // 定义消息信息\n let events = {\n type: type, // 消息类型\n args: args || {} // 消息携带数据\n };\n for (let i = 0;i < messages[type].length; i++) {\n // 执行动作\n messages[type][i].call(this, events)\n }\n },\n // 删除消息\n remove (type, fn) {\n // 消息队列存在\n if (messages[type] instanceof Array) {\n // 从最后一个消息动作遍历\n let i = messages[type].length - 1;\n for (; i >=0; i++) {\n // 存在该消息动作,则移除\n messages[type][i] === fn && messages[type].splice(i ,1);\n }\n }\n }\n }\n})();\n\nexport default Observer;","// 获取URL参数\nconst getUrlParam = function (name) {\n let reg = new RegExp(\"(^|&)\" + name + \"=([^&]*)(&|$)\"); //构造一个含有目标参数的正则表达式对象\n let r = window.location.search.substr(1).match(reg); //匹配目标参数\n if (r != null)\n return decodeURIComponent(r[2]);\n return null; //返回参数值\n};\n\n// 判断ie浏览器版本\nconst IEVersion = function () {\n let userAgent = navigator.userAgent; // 取得浏览器的userAgent字符串\n let isIE = userAgent.indexOf(\"compatible\") > -1 && userAgent.indexOf(\"MSIE\") > -1; //判断是否IE<11浏览器\n let isEdge = userAgent.indexOf(\"Edge\") > -1 && !isIE; // 判断是否IE的Edge浏览器\n let isIE11 = userAgent.indexOf('Trident') > -1 && userAgent.indexOf(\"rv:11.0\") > -1;\n if(isIE) {\n let reIE = new RegExp(\"MSIE (\\\\d+\\\\.\\\\d+);\");\n reIE.test(userAgent);\n let fIEVersion = parseFloat(RegExp[\"$1\"]);\n if(fIEVersion == 7) {\n return 7;\n } else if(fIEVersion == 8) {\n return 8;\n } else if(fIEVersion == 9) {\n return 9;\n } else if(fIEVersion == 10) {\n return 10;\n } else {\n return 6;//IE版本<=7\n }\n } else if(isEdge) {\n return 'edge';//edge\n } else if(isIE11) {\n return 11; //IE11\n } else {\n return false;//不是ie浏览器\n }\n};\n\n// 浏览器滚动到底部时执行fn函数\nconst ScrollBottom = function (fn) {\n let $elem = document.documentElement;\n let $body = document.body;\n let scroll = $elem.scrollTop || $body.scrollTop; // 滚动条滚动的距离\n let clientH = $elem.clientHeight || $body.clientHeight; // 可视窗口总高度\n let scrollH = $elem.scrollHeight || $body.scrollHeight; // 窗口总高度\n let stayBottom = fn() || function () {};\n if (scroll >= scrollH - clientH) {\n stayBottom();\n }\n};\n\nconst explorerType = function () {\n const u = navigator.userAgent;\n const isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1;\n const isiOS = !!u.match(/\\(i[^;]+;( U;)? CPU.+Mac OS X/);\n const isWeixin = u.indexOf('MicroMessenger') > -1;\n const isQQ = u.match(/\\sQQ/i) == \" QQ\";\n\n return {\n isAndroid, isiOS, isWeixin, isQQ\n }\n};\n\nconst scrollToTop = function () {\n let height = document.documentElement.scrollTop;\n clearInterval(window.timer);\n window.timer = null;\n let target = 0;\n window.timer = setInterval(function () {\n target = document.documentElement.scrollTop;\n target -= Math.ceil(target/10); // 做减速运动\n window.scrollTo(0, target);\n if (target == 0) {\n clearInterval(timer);\n window.timer = null;\n }\n }, 10);\n};\n\nconst validInternet = function() {\n return window.navigator.onLine;\n};\n\nexport const Explorer = {\n getUrlParam, IEVersion, ScrollBottom, explorerType, scrollToTop, validInternet\n};\n\nexport default Explorer;\n","const CookieUtil = (function () {\n return {\n set (name, value, attributes) {\n let expires, path;\n if (attributes) {\n expires = attributes.expires || 0;\n path = attributes.path || '/';\n }\n let date = Date.now() + expires * 24 * 60 * 60 * 1000; // cookie过期时间\n date = new Date(date).toUTCString();\n document.cookie = name + \"=\" + encodeURIComponent(value) + ((!expires)?\"\":( \"; expires=\" + date)) + \";path=\" + path + \";\";\n }, // 设置cookie\n setCookies (obj){\n for(let i = 0;i < obj.length;i++){\n this.set(obj[i][0],obj[i][1],obj[i][2]);\n }\n }, // 批量设置cookie\n get (name) {\n if (document.cookie.length > 0) {\n let start = document.cookie.indexOf(name + '=');\n if (start !== -1) {\n start = start + name.length + 1;\n let end = document.cookie.indexOf(';', start);\n if (end === -1) {\n end = document.cookie.length;\n }\n return decodeURIComponent(document.cookie.substring(start, end))/* 获取解码后的cookie值 */\n } else {\n return null;\n }\n } else return null;\n }, // 获取cookie\n remove (name) {\n this.set(name, '', -1);\n }, // 清除特定cookie\n clearCookies (obj) {\n for (let i = obj.length - 1; i >= 0; i--) {\n this.remove(obj[i]);\n }\n this.set(name, '', -1);\n }, // 批量清除cookie\n clearAllCookie: function () {\n let keys = document.cookie.match(/[^ =;]+(?=\\=)/g);\n if (keys) {\n for (let i = keys.length; i--;) {\n document.cookie = keys[i] + '=0;expires=' + new Date(0).toUTCString();\n }\n }\n },// 清除所有cookie\n setCacheData (name, val, cacheDay) {\n // 判断是否支持或开启localStorage\n // 无痕模式下和ie安全模式下localStorage会被禁用\n if (localStorage) {\n localStorage.setItem(name, val);\n } else {\n this.set(name, val, cacheDay || 1000);\n }\n }, // 设置缓存\n getCacheData (name) {\n if (localStorage) {\n return localStorage.getItem(name);\n } else {\n return this.get(name);\n }\n }, // 获取缓存\n removeCacheData (name) {\n if (localStorage) {\n localStorage.removeItem(name);\n } else {\n this.remove(name);\n }\n } // 清除缓存\n }\n});\nexport const Cookie = new CookieUtil();\nexport default Cookie;\n","import base64 from './encrypt/base64';\nimport md5 from './encrypt/md5';\nimport common from './common/index';\nimport valid from './valid';\n// import Country from './common/worldCountry';\nimport explorer from './explorer/explorer';\nimport cookie from './cookie'\nimport observer from './pattern/observer'\n\nexport { Base64 } from './encrypt/base64'\n\nexport { Md5 } from './encrypt/md5'\n\nexport { Common } from './common/index'\n\nexport { Valid } from './valid/index'\n\n// export { Country } from './common/worldCountry'\n\nexport { Explorer } from './explorer/explorer'\n\nexport { Cookie } from './cookie'\n\nexport { Observer } from './pattern/observer'\n\nexport default {\n Base64: base64,\n Md5: md5,\n Explorer: explorer,\n Common: common,\n Valid: valid,\n Cookie: cookie,\n Observer: observer\n};\n"],"sourceRoot":""} -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | test h-utils.js 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "h-utils.js", 3 | "version": "0.5.5", 4 | "description": "js utils", 5 | "main": "dist/utils.min", 6 | "scripts": { 7 | "build": "webpack", 8 | "dev": "webpack-dev-server --config webpack.dev.config.js --hot --inline", 9 | "registry": "npm config set registry https://registry.npmjs.org/ && npm publish" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git+https://github.com/HEJIN2016/js-utils.git" 14 | }, 15 | "keywords": [ 16 | "utils", 17 | "javascript" 18 | ], 19 | "author": "hejin", 20 | "license": "MIT", 21 | "bugs": { 22 | "url": "https://github.com/HEJIN2016/js-utils/issues" 23 | }, 24 | "homepage": "https://github.com/HEJIN2016/js-utils#readme", 25 | "dependencies": { 26 | "babel-preset-env": "^1.7.0", 27 | "webpack": "^4.42.1", 28 | "webpack-cli": "^3.3.11", 29 | "webpack-dev-server": "^3.10.3" 30 | }, 31 | "devDependencies": { 32 | "@babel/core": "^7.9.0", 33 | "@babel/plugin-proposal-export-default-from": "^7.8.3", 34 | "@babel/plugin-transform-runtime": "^7.9.0", 35 | "@babel/preset-env": "^7.9.5", 36 | "@babel/runtime": "^7.9.2", 37 | "babel-loader": "^8.1.0", 38 | "babel-plugin-syntax-dynamic-import": "^6.18.0", 39 | "clean-webpack-plugin": "^3.0.0", 40 | "portfinder": "^1.0.25", 41 | "uglifyjs-webpack-plugin": "^2.2.0" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/common/index.js: -------------------------------------------------------------------------------- 1 | // 百度SEO 2 | const seo = function() { 3 | let bp = document.createElement('script'); 4 | let curProtocol = window.location.protocol.split(':')[0]; 5 | if (curProtocol === 'https') { 6 | bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; 7 | } 8 | else { 9 | bp.src = 'http://push.zhanzhang.baidu.com/push.js'; 10 | } 11 | let s = document.getElementsByTagName("script")[0]; 12 | s.parentNode.insertBefore(bp, s); 13 | }; 14 | 15 | // 函数节流 16 | const throttle = function(method, context) { 17 | clearTimeout(method.tId); 18 | method.tId = setTimeout(function () { 19 | method.call(context); 20 | }.bind(this), context?context:1000); 21 | }; 22 | 23 | // base64位码转blob对象 24 | const dataURLtoBlob = (dataurl)=>{ 25 | let arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1], 26 | bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n); 27 | while(n--){ 28 | u8arr[n] = bstr.charCodeAt(n); 29 | } 30 | return new Blob([u8arr], {type:mime}); 31 | }; 32 | 33 | // 生成随机字符串 34 | function getRandomStr(){ 35 | return Math.random().toString(36).substring(2) 36 | } 37 | 38 | /** 39 | * 将base64/dataurl转成File 40 | * @param dataurl 41 | * @param filename 42 | * @returns {File} 43 | */ 44 | function dataURLtoFile(dataurl, filename) { 45 | let arr = dataurl.split(','), 46 | mime = arr[0].match(/:(.*?);/)[1], 47 | bstr = atob(arr[1]), 48 | n = bstr.length, 49 | u8arr = new Uint8Array(n); 50 | while (n--) { 51 | u8arr[n] = bstr.charCodeAt(n); 52 | } 53 | return new File([u8arr], filename, { type: mime }); 54 | } 55 | 56 | // 获取File 对象或 Blob 对象的临时路径 57 | function getObjectURL(file) { 58 | let url = null; 59 | if (window.createObjectURL) { 60 | // basic 61 | url = window.createObjectURL(file); 62 | } else if (window.URL) { 63 | // mozilla(firefox) 64 | url = window.URL.createObjectURL(file); 65 | } else if (window.webkitURL) { 66 | // webkit or chrome 67 | url = window.webkitURL.createObjectURL(file); 68 | } 69 | return url; 70 | } 71 | 72 | // 获取n-m的随机整数 73 | const getRandomNum = (n, m)=> { 74 | return Math.ceil(Math.random()*(m-n), n); 75 | }; 76 | 77 | // 将数字转成3位分隔符 78 | const splitNum = function (num) { 79 | if (num === null || num === undefined) { 80 | return null; 81 | } 82 | if (typeof num === "number") { 83 | num = num.toString() 84 | } 85 | return num.replace(/\B(?=(?:\d{3})+\b)/g, ',') 86 | }; 87 | 88 | // 字符串/数字数组去重 89 | function unique(arr) { 90 | return Array.from(new Set(arr)); 91 | } 92 | 93 | // 生成uuid 94 | function getUuid() { 95 | let s = []; 96 | let hexDigits = "0123456789abcdef"; 97 | for (let i = 0; i < 36; i++) { 98 | s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1); 99 | } 100 | s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010 101 | s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01 102 | s[8] = s[13] = s[18] = s[23] = "-"; 103 | 104 | return s.join(""); 105 | } 106 | 107 | // 过滤掉某个字符串中的中文字符 108 | function filterChineseWord(str) { 109 | return str.replace(/[\u4E00-\u9FA5]/g, ''); 110 | } 111 | 112 | /** 113 | * nodejs获取本地ip 114 | * @param os node.js os模块 115 | * @returns {*} 116 | */ 117 | function getIPAddress(os) { 118 | if (!os) return ''; 119 | let interfaces = os.networkInterfaces(); 120 | for (let devName in interfaces) { 121 | let iface = interfaces[devName]; 122 | for (let i = 0; i < iface.length; i++) { 123 | let alias = iface[i]; 124 | if (alias.family === 'IPv4' && alias.address !== '127.0.0.1' && !alias.internal) { 125 | return alias.address; 126 | } 127 | } 128 | } 129 | } 130 | 131 | /** 132 | * 获取元素实际样式值 133 | * @param el dom元素 134 | * @param styleName 样式名 135 | */ 136 | function getStyle(el, styleName) { 137 | if (el.currentStyle) return el.currentStyle[styleName]; 138 | if (getComputedStyle) return window.getComputedStyle(el, null)[styleName]; 139 | return el.style[styleName]; 140 | } 141 | 142 | // 优雅降级requestAnimationFrame 143 | const requestAnimationF = (function () { 144 | return window.requestAnimationFrame || 145 | window.webkitRequestAnimationFrame || 146 | window.mozRequestAnimationFrame || 147 | window.oRequestAnimationFrame || 148 | // if all else fails, use setTimeout 149 | function (callback) { 150 | return window.setTimeout(callback, 1000 / 60); // shoot for 60 fps 151 | }; 152 | })(); 153 | 154 | // 优雅降级cancelAnimationFrame 155 | const cancelAnimationF = (function () { 156 | return window.cancelAnimationFrame || 157 | window.webkitCancelAnimationFrame || 158 | window.mozCancelAnimationFrame || 159 | window.oCancelAnimationFrame || 160 | function (id) { 161 | window.clearTimeout(id); 162 | }; 163 | })(); 164 | 165 | 166 | /** 167 | * 获取元素实际高度 168 | * @param el dom元素 169 | * @returns {number} 元素高度 170 | */ 171 | function getHeight(el) { 172 | let height; 173 | // 已隐藏的元素 174 | if (getStyle(el, "display") === "none") { 175 | el.style.position = "absolute"; 176 | el.style.visibility = "hidden"; 177 | el.style.display = "block"; 178 | height = getStyle(el, "height"); 179 | el.style.position = ""; 180 | el.style.visibility = ""; 181 | el.style.display = ""; 182 | return parseFloat(height); 183 | } 184 | return parseFloat(getStyle(el, "height")); 185 | } 186 | 187 | /** 188 | * 获取已隐藏元素的css值 189 | * @param el 190 | * @param styleName 191 | * @returns {*} 192 | */ 193 | function getCurrentStyle(el, styleName) { 194 | let styleValue; 195 | // 已隐藏的元素 196 | if (getStyle(el, "display") === "none") { 197 | el.style.position = "absolute"; 198 | el.style.visibility = "hidden"; 199 | el.style.display = "block"; 200 | styleValue = getStyle(el, styleName); 201 | el.style.position = ""; 202 | el.style.visibility = ""; 203 | el.style.display = ""; 204 | return (styleValue); 205 | } 206 | return (getStyle(el, styleName)); 207 | } 208 | 209 | /** 210 | * 优化实现sildeToggle效果 211 | * @param el dom元素 212 | * @param time 动画时长,单位ms,默认值300 213 | * @param fn 回调函数 214 | */ 215 | function slideToggle(el, time, fn) { 216 | if (!el) return false; 217 | time = time || 300; 218 | if (el.dataUid) return false; // 如该dom元素已有动画未处理完,则必须等到动画结束才执行 219 | 220 | cancelAnimationF(el.dataUid); 221 | 222 | // 已隐藏的元素,下拉 223 | if (getStyle(el, "display") === "none" || getHeight(el) === 0) { 224 | down(el, time, fn); 225 | } else { 226 | up(el, time, fn) 227 | } 228 | } 229 | 230 | function down(el, time, fn) { 231 | let aniSplitTime = Date.now(); 232 | 233 | let height = 0, paddingTop = 0, paddingBottom = 0; 234 | let totalHeight = parseFloat(getCurrentStyle(el, "height")); 235 | let totalPaddingTop = parseFloat(getCurrentStyle(el, "paddingTop")); 236 | let totalPaddingBottom = parseFloat(getCurrentStyle(el, "paddingBottom")); 237 | 238 | let basePaddingBottom = totalPaddingBottom/time; 239 | let basePaddingTop = totalPaddingBottom/time; 240 | let baseHeight = totalHeight/time; 241 | 242 | el.style.overflow = "hidden"; 243 | el.style.display = "block"; 244 | 245 | el.dataUid = requestAnimationF(function go(){ 246 | let aniTime = Date.now(); 247 | let splitTime = aniTime - aniSplitTime; 248 | aniSplitTime = aniTime; 249 | let splitPaddingBottom = basePaddingBottom*splitTime; 250 | let splitPaddingTop = basePaddingTop*splitTime; 251 | let splitHeight = baseHeight*splitTime; 252 | 253 | if (height >= totalHeight){ 254 | el.style.overflow = ""; 255 | el.style.height = ""; 256 | el.style.paddingTop = ""; 257 | el.style.paddingBottom = ""; 258 | 259 | if (fn && typeof fn === "function") fn(); 260 | cancelAnimationF(el.dataUid); 261 | el.dataUid = null; 262 | delete el.dataUid; 263 | } else { 264 | el.style.height = height + "px"; 265 | el.style.paddingTop = paddingTop + "px"; 266 | el.style.paddingBottom = paddingBottom + "px"; 267 | el.dataUid = requestAnimationF(go); 268 | } 269 | height = height + splitHeight; 270 | paddingTop = paddingTop + splitPaddingTop; 271 | paddingBottom = paddingBottom + splitPaddingBottom; 272 | }); 273 | } 274 | 275 | function up(el, time, fn) { 276 | // 上拉 277 | let aniSplitTime = Date.now(); 278 | let height = getHeight(el); 279 | let paddingTop = parseFloat(getStyle(el, "paddingTop")); 280 | let paddingBottom = parseFloat(getStyle(el, "paddingBottom")); 281 | el.style.overflow = "hidden"; 282 | 283 | let basePaddingBottom = paddingBottom/time; 284 | let basePaddingTop = paddingTop/time; 285 | let baseHeight = height/time; 286 | 287 | el.dataUid = requestAnimationF(function go(){ 288 | let aniTime = Date.now(); 289 | let splitTime = aniTime - aniSplitTime; 290 | aniSplitTime = aniTime; 291 | let splitPaddingBottom = basePaddingBottom*splitTime; 292 | let splitPaddingTop = basePaddingTop*splitTime; 293 | let splitHeight = baseHeight*splitTime; 294 | 295 | if (height <= 0) { 296 | el.style.height = 0; 297 | el.style.paddingTop = 0; 298 | el.style.paddingBottom = 0; 299 | 300 | setTimeout(()=>{ 301 | el.style.height = ""; 302 | el.style.overflow = ""; 303 | el.style.paddingTop = ""; 304 | el.style.paddingBottom = ""; 305 | el.style.display = "none"; 306 | },0); 307 | 308 | if (fn && typeof fn === "function") fn(); 309 | cancelAnimationF(el.dataUid); 310 | el.dataUid = null; 311 | delete el.dataUid; 312 | } else { 313 | el.style.height = height + "px"; 314 | el.style.paddingTop = paddingTop + "px"; 315 | el.style.paddingBottom = paddingBottom + "px"; 316 | el.dataUid = requestAnimationF(go); 317 | } 318 | 319 | height = height - splitHeight; 320 | paddingBottom = paddingBottom - splitPaddingBottom; 321 | paddingTop = paddingTop - splitPaddingTop; 322 | }); 323 | } 324 | 325 | /** 326 | * 优化实现jquery slideDown效果 327 | * @param el dom元素 328 | * @param time 动画时长,单位ms,默认值300 329 | * @param fn 回调函数 330 | */ 331 | function slideDown(el, time, fn) { 332 | if (!el) return false; 333 | time = time || 300; 334 | if (el.dataUid) return false; // 如该dom元素已有动画未处理完,则必须等到动画结束才执行 335 | 336 | cancelAnimationF(el.dataUid); 337 | if (getStyle(el, "display") === "none" || getHeight(el) === 0) { 338 | down(el, time, fn); 339 | } 340 | } 341 | 342 | /** 343 | * 优化实现jquery slideUp效果 344 | * @param el dom元素 345 | * @param time 动画时长,单位ms,默认值300 346 | * @param fn 回调函数 347 | */ 348 | function slideUp(el, time, fn) { 349 | if (!el) return false; 350 | time = time || 300; 351 | if (el.dataUid) return false; // 如该dom元素已有动画未处理完,则必须等到动画结束才执行 352 | 353 | cancelAnimationF(el.dataUid); 354 | 355 | if (getStyle(el, "display") === "none" || getHeight(el) === 0) { 356 | 357 | } else { 358 | up(el, time, fn); 359 | } 360 | } 361 | 362 | /** 363 | * 获取当天的23:59:59的Date对象(当天最后1ms的Date对象) 364 | * @param date (默认值new Date()) 365 | * @returns {Date} 366 | */ 367 | function getDayLastMsDate(date = new Date()) { 368 | if (!date instanceof Date) { 369 | throw new Error("function params type error"); 370 | } 371 | return new Date(new Date(date.toLocaleDateString()).getTime()+24*60*60*1000-1) 372 | } 373 | 374 | /** 375 | * 获取当天的00:00的Date对象(当天最开始1ms的Date对象) 376 | * @param date (默认值new Date()) 377 | * @returns {Date} 378 | */ 379 | function getDayFirstMsDate(date = new Date()) { 380 | if (!date instanceof Date) { 381 | throw new Error("function params type error"); 382 | } 383 | return new Date(date.toLocaleDateString()) 384 | } 385 | 386 | /* 387 | 压缩图片 388 | dataUrl: dataUrl, 389 | obj:{ height, width } 压缩之后的图片宽高 390 | type:压缩完之后的图片类型 391 | */ 392 | function photoCompress(dataUrl, obj, type = "image/png"){ 393 | return new Promise((resolve, reject) => { 394 | let img = new Image(); 395 | img.src = dataUrl; 396 | img.onload = function(){ 397 | let that = this; 398 | // 默认按比例压缩 399 | let w = that.width, 400 | h = that.height, 401 | scale = w / h; 402 | if (h >= obj.height) { 403 | h = obj.height; 404 | } 405 | w = (h * scale); 406 | 407 | let quality = 1; // 默认图片质量为1 408 | //生成canvas 409 | let canvas = document.createElement('canvas'); 410 | let ctx = canvas.getContext('2d'); 411 | // 创建属性节点 412 | let anw = document.createAttribute("width"); 413 | anw.nodeValue = w; 414 | let anh = document.createAttribute("height"); 415 | anh.nodeValue = h; 416 | canvas.setAttributeNode(anw); 417 | canvas.setAttributeNode(anh); 418 | ctx.drawImage(that, 0, 0, w, h); 419 | // 图像质量 420 | if(obj.quality && obj.quality <= 1 && obj.quality > 0){ 421 | quality = obj.quality; 422 | } 423 | // quality值越小,所绘制出的图像越模糊 424 | let base64 = canvas.toDataURL(type, quality); 425 | // 回调函数返回base64的值 426 | resolve(base64); 427 | }; 428 | img.onerror = ()=>{ 429 | reject(); 430 | } 431 | }) 432 | 433 | } 434 | 435 | // 获取文件格式(后缀) 436 | function getFileType(fileName = '') { 437 | let index = fileName.lastIndexOf("."); 438 | if (index >= 0) return fileName.substring(index + 1); 439 | return ""; 440 | } 441 | 442 | // 重排数组(洗牌算法) 443 | function arrayShuffle(input) { 444 | for (var i = input.length-1; i >=0; i--) { 445 | var randomIndex = Math.floor(Math.random()*(i+1)); 446 | var itemAtIndex = input[randomIndex]; 447 | input[randomIndex] = input[i]; 448 | input[i] = itemAtIndex; 449 | } 450 | return input; 451 | } 452 | 453 | export const Common = { 454 | seo, 455 | throttle, 456 | dataURLtoBlob, 457 | getRandomNum, 458 | splitNum, 459 | getUuid, 460 | getRandomStr, 461 | unique, 462 | filterChineseWord, 463 | getIPAddress, 464 | getStyle, 465 | getCurrentStyle, 466 | slideToggle, 467 | slideUp, 468 | slideDown, 469 | getObjectURL, 470 | dataURLtoFile, 471 | getDayLastMsDate, 472 | getDayFirstMsDate, 473 | photoCompress, 474 | getFileType, 475 | arrayShuffle 476 | }; 477 | 478 | export default Common; 479 | 480 | 481 | -------------------------------------------------------------------------------- /src/cookie.js: -------------------------------------------------------------------------------- 1 | const CookieUtil = (function () { 2 | return { 3 | set (name, value, attributes) { 4 | let expires, path; 5 | if (attributes) { 6 | expires = attributes.expires || 0; 7 | path = attributes.path || '/'; 8 | } 9 | let date = Date.now() + expires * 24 * 60 * 60 * 1000; // cookie过期时间 10 | date = new Date(date).toUTCString(); 11 | document.cookie = name + "=" + encodeURIComponent(value) + ((!expires)?"":( "; expires=" + date)) + ";path=" + path + ";"; 12 | }, // 设置cookie 13 | setCookies (obj){ 14 | for(let i = 0;i < obj.length;i++){ 15 | this.set(obj[i][0],obj[i][1],obj[i][2]); 16 | } 17 | }, // 批量设置cookie 18 | get (name) { 19 | if (document.cookie.length > 0) { 20 | let start = document.cookie.indexOf(name + '='); 21 | if (start !== -1) { 22 | start = start + name.length + 1; 23 | let end = document.cookie.indexOf(';', start); 24 | if (end === -1) { 25 | end = document.cookie.length; 26 | } 27 | return decodeURIComponent(document.cookie.substring(start, end))/* 获取解码后的cookie值 */ 28 | } else { 29 | return null; 30 | } 31 | } else return null; 32 | }, // 获取cookie 33 | remove (name) { 34 | this.set(name, '', -1); 35 | }, // 清除特定cookie 36 | clearCookies (obj) { 37 | for (let i = obj.length - 1; i >= 0; i--) { 38 | this.remove(obj[i]); 39 | } 40 | this.set(name, '', -1); 41 | }, // 批量清除cookie 42 | clearAllCookie: function () { 43 | let keys = document.cookie.match(/[^ =;]+(?=\=)/g); 44 | if (keys) { 45 | for (let i = keys.length; i--;) { 46 | document.cookie = keys[i] + '=0;expires=' + new Date(0).toUTCString(); 47 | } 48 | } 49 | },// 清除所有cookie 50 | setCacheData (name, val, cacheDay) { 51 | // 判断是否支持或开启localStorage 52 | // 无痕模式下和ie安全模式下localStorage会被禁用 53 | if (localStorage) { 54 | localStorage.setItem(name, val); 55 | } else { 56 | this.set(name, val, cacheDay || 1000); 57 | } 58 | }, // 设置缓存 59 | getCacheData (name) { 60 | if (localStorage) { 61 | return localStorage.getItem(name); 62 | } else { 63 | return this.get(name); 64 | } 65 | }, // 获取缓存 66 | removeCacheData (name) { 67 | if (localStorage) { 68 | localStorage.removeItem(name); 69 | } else { 70 | this.remove(name); 71 | } 72 | } // 清除缓存 73 | } 74 | }); 75 | export const Cookie = new CookieUtil(); 76 | export default Cookie; 77 | -------------------------------------------------------------------------------- /src/encrypt/base64.js: -------------------------------------------------------------------------------- 1 | export const Base64 = { 2 | _keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", 3 | encode: function(e) { 4 | let t = ""; 5 | let n, r, i, s, o, u, a; 6 | let f = 0; 7 | e = Base64._utf8_encode(e); 8 | while (f < e.length) { 9 | n = e.charCodeAt(f++); 10 | r = e.charCodeAt(f++); 11 | i = e.charCodeAt(f++); 12 | s = n >> 2; 13 | o = (n & 3) << 4 | r >> 4; 14 | u = (r & 15) << 2 | i >> 6; 15 | a = i & 63; 16 | if (isNaN(r)) { 17 | u = a = 64 18 | } else if (isNaN(i)) { 19 | a = 64 20 | } 21 | t = t + this._keyStr.charAt(s) + this._keyStr.charAt(o) + this._keyStr.charAt(u) + this._keyStr.charAt(a) 22 | } 23 | return t 24 | }, 25 | decode: function(e) { 26 | let t = ""; 27 | let n, r, i; 28 | let s, o, u, a; 29 | let f = 0; 30 | e=e.replace(/[^A-Za-z0-9+/=]/g,""); 31 | while (f < e.length) { 32 | s = this._keyStr.indexOf(e.charAt(f++)); 33 | o = this._keyStr.indexOf(e.charAt(f++)); 34 | u = this._keyStr.indexOf(e.charAt(f++)); 35 | a = this._keyStr.indexOf(e.charAt(f++)); 36 | n = s << 2 | o >> 4; 37 | r = (o & 15) << 4 | u >> 2; 38 | i = (u & 3) << 6 | a; 39 | t = t + String.fromCharCode(n); 40 | if (u != 64) { 41 | t = t + String.fromCharCode(r) 42 | } 43 | if (a != 64) { 44 | t = t + String.fromCharCode(i) 45 | } 46 | } 47 | t = Base64._utf8_decode(t); 48 | return t 49 | }, 50 | _utf8_encode: function(e) { 51 | e = e.replace(/rn/g, "n"); 52 | let t = ""; 53 | for (let n = 0; n < e.length; n++) { 54 | let r = e.charCodeAt(n); 55 | if (r < 128) { 56 | t += String.fromCharCode(r) 57 | } else if (r > 127 && r < 2048) { 58 | t += String.fromCharCode(r >> 6 | 192); 59 | t += String.fromCharCode(r & 63 | 128) 60 | } else { 61 | t += String.fromCharCode(r >> 12 | 224); 62 | t += String.fromCharCode(r >> 6 & 63 | 128); 63 | t += String.fromCharCode(r & 63 | 128) 64 | } 65 | } 66 | return t 67 | }, 68 | _utf8_decode: function(e) { 69 | let t = ""; 70 | let n = 0; 71 | let r = c1 = c2 = 0; 72 | while (n < e.length) { 73 | r = e.charCodeAt(n); 74 | if (r < 128) { 75 | t += String.fromCharCode(r); 76 | n++ 77 | } else if (r > 191 && r < 224) { 78 | c2 = e.charCodeAt(n + 1); 79 | t += String.fromCharCode((r & 31) << 6 | c2 & 63); 80 | n += 2 81 | } else { 82 | c2 = e.charCodeAt(n + 1); 83 | c3 = e.charCodeAt(n + 2); 84 | t += String.fromCharCode((r & 15) << 12 | (c2 & 63) << 6 | c3 & 63); 85 | n += 3 86 | } 87 | } 88 | return t 89 | } 90 | }; 91 | 92 | export default Base64; 93 | -------------------------------------------------------------------------------- /src/encrypt/md5.js: -------------------------------------------------------------------------------- 1 | export const Md5 = function(string) { 2 | function md5_RotateLeft(lValue, iShiftBits) { 3 | return (lValue << iShiftBits) | (lValue >>> (32 - iShiftBits)); 4 | } 5 | function md5_AddUnsigned(lX, lY) { 6 | var lX4, lY4, lX8, lY8, lResult; 7 | lX8 = (lX & 0x80000000); 8 | lY8 = (lY & 0x80000000); 9 | lX4 = (lX & 0x40000000); 10 | lY4 = (lY & 0x40000000); 11 | lResult = (lX & 0x3FFFFFFF) + (lY & 0x3FFFFFFF); 12 | if (lX4 & lY4) { 13 | return (lResult ^ 0x80000000 ^ lX8 ^ lY8); 14 | } 15 | if (lX4 | lY4) { 16 | if (lResult & 0x40000000) { 17 | return (lResult ^ 0xC0000000 ^ lX8 ^ lY8); 18 | } else { 19 | return (lResult ^ 0x40000000 ^ lX8 ^ lY8); 20 | } 21 | } else { 22 | return (lResult ^ lX8 ^ lY8); 23 | } 24 | } 25 | function md5_F(x, y, z) { 26 | return (x & y) | ((~x) & z); 27 | } 28 | function md5_G(x, y, z) { 29 | return (x & z) | (y & (~z)); 30 | } 31 | function md5_H(x, y, z) { 32 | return (x ^ y ^ z); 33 | } 34 | function md5_I(x, y, z) { 35 | return (y ^ (x | (~z))); 36 | } 37 | function md5_FF(a, b, c, d, x, s, ac) { 38 | a = md5_AddUnsigned(a, md5_AddUnsigned(md5_AddUnsigned(md5_F(b, c, d), x), ac)); 39 | return md5_AddUnsigned(md5_RotateLeft(a, s), b); 40 | }; 41 | function md5_GG(a, b, c, d, x, s, ac) { 42 | a = md5_AddUnsigned(a, md5_AddUnsigned(md5_AddUnsigned(md5_G(b, c, d), x), ac)); 43 | return md5_AddUnsigned(md5_RotateLeft(a, s), b); 44 | }; 45 | function md5_HH(a, b, c, d, x, s, ac) { 46 | a = md5_AddUnsigned(a, md5_AddUnsigned(md5_AddUnsigned(md5_H(b, c, d), x), ac)); 47 | return md5_AddUnsigned(md5_RotateLeft(a, s), b); 48 | }; 49 | function md5_II(a, b, c, d, x, s, ac) { 50 | a = md5_AddUnsigned(a, md5_AddUnsigned(md5_AddUnsigned(md5_I(b, c, d), x), ac)); 51 | return md5_AddUnsigned(md5_RotateLeft(a, s), b); 52 | }; 53 | function md5_ConvertToWordArray(string) { 54 | var lWordCount; 55 | var lMessageLength = string.length; 56 | var lNumberOfWords_temp1 = lMessageLength + 8; 57 | var lNumberOfWords_temp2 = (lNumberOfWords_temp1 - (lNumberOfWords_temp1 % 64)) / 64; 58 | var lNumberOfWords = (lNumberOfWords_temp2 + 1) * 16; 59 | var lWordArray = Array(lNumberOfWords - 1); 60 | var lBytePosition = 0; 61 | var lByteCount = 0; 62 | while (lByteCount < lMessageLength) { 63 | lWordCount = (lByteCount - (lByteCount % 4)) / 4; 64 | lBytePosition = (lByteCount % 4) * 8; 65 | lWordArray[lWordCount] = (lWordArray[lWordCount] | (string.charCodeAt(lByteCount) << lBytePosition)); 66 | lByteCount++; 67 | } 68 | lWordCount = (lByteCount - (lByteCount % 4)) / 4; 69 | lBytePosition = (lByteCount % 4) * 8; 70 | lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80 << lBytePosition); 71 | lWordArray[lNumberOfWords - 2] = lMessageLength << 3; 72 | lWordArray[lNumberOfWords - 1] = lMessageLength >>> 29; 73 | return lWordArray; 74 | }; 75 | function md5_WordToHex(lValue) { 76 | var WordToHexValue = "", 77 | WordToHexValue_temp = "", 78 | lByte, lCount; 79 | for (lCount = 0; lCount <= 3; lCount++) { 80 | lByte = (lValue >>> (lCount * 8)) & 255; 81 | WordToHexValue_temp = "0" + lByte.toString(16); 82 | WordToHexValue = WordToHexValue + WordToHexValue_temp.substr(WordToHexValue_temp.length - 2, 2); 83 | } 84 | return WordToHexValue; 85 | }; 86 | function md5_Utf8Encode(string) { 87 | string = string.replace(/\r\n/g, "\n"); 88 | var utftext = ""; 89 | for (var n = 0; n < string.length; n++) { 90 | var c = string.charCodeAt(n); 91 | if (c < 128) { 92 | utftext += String.fromCharCode(c); 93 | } else if ((c > 127) && (c < 2048)) { 94 | utftext += String.fromCharCode((c >> 6) | 192); 95 | utftext += String.fromCharCode((c & 63) | 128); 96 | } else { 97 | utftext += String.fromCharCode((c >> 12) | 224); 98 | utftext += String.fromCharCode(((c >> 6) & 63) | 128); 99 | utftext += String.fromCharCode((c & 63) | 128); 100 | } 101 | } 102 | return utftext; 103 | }; 104 | var x = Array(); 105 | var k, AA, BB, CC, DD, a, b, c, d; 106 | var S11 = 7, 107 | S12 = 12, 108 | S13 = 17, 109 | S14 = 22; 110 | var S21 = 5, 111 | S22 = 9, 112 | S23 = 14, 113 | S24 = 20; 114 | var S31 = 4, 115 | S32 = 11, 116 | S33 = 16, 117 | S34 = 23; 118 | var S41 = 6, 119 | S42 = 10, 120 | S43 = 15, 121 | S44 = 21; 122 | string = md5_Utf8Encode(string); 123 | x = md5_ConvertToWordArray(string); 124 | a = 0x67452301; 125 | b = 0xEFCDAB89; 126 | c = 0x98BADCFE; 127 | d = 0x10325476; 128 | for (k = 0; k < x.length; k += 16) { 129 | AA = a; 130 | BB = b; 131 | CC = c; 132 | DD = d; 133 | a = md5_FF(a, b, c, d, x[k + 0], S11, 0xD76AA478); 134 | d = md5_FF(d, a, b, c, x[k + 1], S12, 0xE8C7B756); 135 | c = md5_FF(c, d, a, b, x[k + 2], S13, 0x242070DB); 136 | b = md5_FF(b, c, d, a, x[k + 3], S14, 0xC1BDCEEE); 137 | a = md5_FF(a, b, c, d, x[k + 4], S11, 0xF57C0FAF); 138 | d = md5_FF(d, a, b, c, x[k + 5], S12, 0x4787C62A); 139 | c = md5_FF(c, d, a, b, x[k + 6], S13, 0xA8304613); 140 | b = md5_FF(b, c, d, a, x[k + 7], S14, 0xFD469501); 141 | a = md5_FF(a, b, c, d, x[k + 8], S11, 0x698098D8); 142 | d = md5_FF(d, a, b, c, x[k + 9], S12, 0x8B44F7AF); 143 | c = md5_FF(c, d, a, b, x[k + 10], S13, 0xFFFF5BB1); 144 | b = md5_FF(b, c, d, a, x[k + 11], S14, 0x895CD7BE); 145 | a = md5_FF(a, b, c, d, x[k + 12], S11, 0x6B901122); 146 | d = md5_FF(d, a, b, c, x[k + 13], S12, 0xFD987193); 147 | c = md5_FF(c, d, a, b, x[k + 14], S13, 0xA679438E); 148 | b = md5_FF(b, c, d, a, x[k + 15], S14, 0x49B40821); 149 | a = md5_GG(a, b, c, d, x[k + 1], S21, 0xF61E2562); 150 | d = md5_GG(d, a, b, c, x[k + 6], S22, 0xC040B340); 151 | c = md5_GG(c, d, a, b, x[k + 11], S23, 0x265E5A51); 152 | b = md5_GG(b, c, d, a, x[k + 0], S24, 0xE9B6C7AA); 153 | a = md5_GG(a, b, c, d, x[k + 5], S21, 0xD62F105D); 154 | d = md5_GG(d, a, b, c, x[k + 10], S22, 0x2441453); 155 | c = md5_GG(c, d, a, b, x[k + 15], S23, 0xD8A1E681); 156 | b = md5_GG(b, c, d, a, x[k + 4], S24, 0xE7D3FBC8); 157 | a = md5_GG(a, b, c, d, x[k + 9], S21, 0x21E1CDE6); 158 | d = md5_GG(d, a, b, c, x[k + 14], S22, 0xC33707D6); 159 | c = md5_GG(c, d, a, b, x[k + 3], S23, 0xF4D50D87); 160 | b = md5_GG(b, c, d, a, x[k + 8], S24, 0x455A14ED); 161 | a = md5_GG(a, b, c, d, x[k + 13], S21, 0xA9E3E905); 162 | d = md5_GG(d, a, b, c, x[k + 2], S22, 0xFCEFA3F8); 163 | c = md5_GG(c, d, a, b, x[k + 7], S23, 0x676F02D9); 164 | b = md5_GG(b, c, d, a, x[k + 12], S24, 0x8D2A4C8A); 165 | a = md5_HH(a, b, c, d, x[k + 5], S31, 0xFFFA3942); 166 | d = md5_HH(d, a, b, c, x[k + 8], S32, 0x8771F681); 167 | c = md5_HH(c, d, a, b, x[k + 11], S33, 0x6D9D6122); 168 | b = md5_HH(b, c, d, a, x[k + 14], S34, 0xFDE5380C); 169 | a = md5_HH(a, b, c, d, x[k + 1], S31, 0xA4BEEA44); 170 | d = md5_HH(d, a, b, c, x[k + 4], S32, 0x4BDECFA9); 171 | c = md5_HH(c, d, a, b, x[k + 7], S33, 0xF6BB4B60); 172 | b = md5_HH(b, c, d, a, x[k + 10], S34, 0xBEBFBC70); 173 | a = md5_HH(a, b, c, d, x[k + 13], S31, 0x289B7EC6); 174 | d = md5_HH(d, a, b, c, x[k + 0], S32, 0xEAA127FA); 175 | c = md5_HH(c, d, a, b, x[k + 3], S33, 0xD4EF3085); 176 | b = md5_HH(b, c, d, a, x[k + 6], S34, 0x4881D05); 177 | a = md5_HH(a, b, c, d, x[k + 9], S31, 0xD9D4D039); 178 | d = md5_HH(d, a, b, c, x[k + 12], S32, 0xE6DB99E5); 179 | c = md5_HH(c, d, a, b, x[k + 15], S33, 0x1FA27CF8); 180 | b = md5_HH(b, c, d, a, x[k + 2], S34, 0xC4AC5665); 181 | a = md5_II(a, b, c, d, x[k + 0], S41, 0xF4292244); 182 | d = md5_II(d, a, b, c, x[k + 7], S42, 0x432AFF97); 183 | c = md5_II(c, d, a, b, x[k + 14], S43, 0xAB9423A7); 184 | b = md5_II(b, c, d, a, x[k + 5], S44, 0xFC93A039); 185 | a = md5_II(a, b, c, d, x[k + 12], S41, 0x655B59C3); 186 | d = md5_II(d, a, b, c, x[k + 3], S42, 0x8F0CCC92); 187 | c = md5_II(c, d, a, b, x[k + 10], S43, 0xFFEFF47D); 188 | b = md5_II(b, c, d, a, x[k + 1], S44, 0x85845DD1); 189 | a = md5_II(a, b, c, d, x[k + 8], S41, 0x6FA87E4F); 190 | d = md5_II(d, a, b, c, x[k + 15], S42, 0xFE2CE6E0); 191 | c = md5_II(c, d, a, b, x[k + 6], S43, 0xA3014314); 192 | b = md5_II(b, c, d, a, x[k + 13], S44, 0x4E0811A1); 193 | a = md5_II(a, b, c, d, x[k + 4], S41, 0xF7537E82); 194 | d = md5_II(d, a, b, c, x[k + 11], S42, 0xBD3AF235); 195 | c = md5_II(c, d, a, b, x[k + 2], S43, 0x2AD7D2BB); 196 | b = md5_II(b, c, d, a, x[k + 9], S44, 0xEB86D391); 197 | a = md5_AddUnsigned(a, AA); 198 | b = md5_AddUnsigned(b, BB); 199 | c = md5_AddUnsigned(c, CC); 200 | d = md5_AddUnsigned(d, DD); 201 | } 202 | return (md5_WordToHex(a) + md5_WordToHex(b) + md5_WordToHex(c) + md5_WordToHex(d)).toLowerCase(); 203 | } 204 | 205 | export default Md5; -------------------------------------------------------------------------------- /src/explorer/explorer.js: -------------------------------------------------------------------------------- 1 | // 获取URL参数 2 | const getUrlParam = function (name) { 3 | let reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)"); //构造一个含有目标参数的正则表达式对象 4 | let r = window.location.search.substr(1).match(reg); //匹配目标参数 5 | if (r != null) 6 | return decodeURIComponent(r[2]); 7 | return null; //返回参数值 8 | }; 9 | 10 | // 判断ie浏览器版本 11 | const IEVersion = function () { 12 | let userAgent = navigator.userAgent; // 取得浏览器的userAgent字符串 13 | let isIE = userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1; //判断是否IE<11浏览器 14 | let isEdge = userAgent.indexOf("Edge") > -1 && !isIE; // 判断是否IE的Edge浏览器 15 | let isIE11 = userAgent.indexOf('Trident') > -1 && userAgent.indexOf("rv:11.0") > -1; 16 | if(isIE) { 17 | let reIE = new RegExp("MSIE (\\d+\\.\\d+);"); 18 | reIE.test(userAgent); 19 | let fIEVersion = parseFloat(RegExp["$1"]); 20 | if(fIEVersion == 7) { 21 | return 7; 22 | } else if(fIEVersion == 8) { 23 | return 8; 24 | } else if(fIEVersion == 9) { 25 | return 9; 26 | } else if(fIEVersion == 10) { 27 | return 10; 28 | } else { 29 | return 6;//IE版本<=7 30 | } 31 | } else if(isEdge) { 32 | return 'edge';//edge 33 | } else if(isIE11) { 34 | return 11; //IE11 35 | } else { 36 | return false;//不是ie浏览器 37 | } 38 | }; 39 | 40 | // 浏览器滚动到底部时执行fn函数 41 | const ScrollBottom = function (fn) { 42 | let $elem = document.documentElement; 43 | let $body = document.body; 44 | let scroll = $elem.scrollTop || $body.scrollTop; // 滚动条滚动的距离 45 | let clientH = $elem.clientHeight || $body.clientHeight; // 可视窗口总高度 46 | let scrollH = $elem.scrollHeight || $body.scrollHeight; // 窗口总高度 47 | let stayBottom = fn() || function () {}; 48 | if (scroll >= scrollH - clientH) { 49 | stayBottom(); 50 | } 51 | }; 52 | 53 | const explorerType = function () { 54 | const u = navigator.userAgent; 55 | const isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1; 56 | const isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); 57 | const isWeixin = u.indexOf('MicroMessenger') > -1; 58 | const isQQ = u.match(/\sQQ/i) == " QQ"; 59 | 60 | return { 61 | isAndroid, isiOS, isWeixin, isQQ 62 | } 63 | }; 64 | 65 | const scrollToTop = function () { 66 | let height = document.documentElement.scrollTop; 67 | clearInterval(window.timer); 68 | window.timer = null; 69 | let target = 0; 70 | window.timer = setInterval(function () { 71 | target = document.documentElement.scrollTop; 72 | target -= Math.ceil(target/10); // 做减速运动 73 | window.scrollTo(0, target); 74 | if (target == 0) { 75 | clearInterval(timer); 76 | window.timer = null; 77 | } 78 | }, 10); 79 | }; 80 | 81 | const validInternet = function() { 82 | return window.navigator.onLine; 83 | }; 84 | 85 | export const Explorer = { 86 | getUrlParam, IEVersion, ScrollBottom, explorerType, scrollToTop, validInternet 87 | }; 88 | 89 | export default Explorer; 90 | -------------------------------------------------------------------------------- /src/export.js: -------------------------------------------------------------------------------- 1 | export { Base64 } from './encrypt/base64' 2 | 3 | export { Md5 } from './encrypt/md5' 4 | 5 | export { Index } from './common' 6 | 7 | export { Index } from './valid' 8 | 9 | // export { Country } from './common/worldCountry' 10 | 11 | export { Explorer } from './explorer/explorer' 12 | 13 | export { Cookie } from './cookie' 14 | 15 | export { Observer } from './pattern/observer' -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import base64 from './encrypt/base64'; 2 | import md5 from './encrypt/md5'; 3 | import common from './common/index'; 4 | import valid from './valid'; 5 | // import Country from './common/worldCountry'; 6 | import explorer from './explorer/explorer'; 7 | import cookie from './cookie' 8 | import observer from './pattern/observer' 9 | 10 | export { Base64 } from './encrypt/base64' 11 | 12 | export { Md5 } from './encrypt/md5' 13 | 14 | export { Common } from './common/index' 15 | 16 | export { Valid } from './valid/index' 17 | 18 | // export { Country } from './common/worldCountry' 19 | 20 | export { Explorer } from './explorer/explorer' 21 | 22 | export { Cookie } from './cookie' 23 | 24 | export { Observer } from './pattern/observer' 25 | 26 | export default { 27 | Base64: base64, 28 | Md5: md5, 29 | Explorer: explorer, 30 | Common: common, 31 | Valid: valid, 32 | Cookie: cookie, 33 | Observer: observer 34 | }; 35 | -------------------------------------------------------------------------------- /src/pattern/observer.js: -------------------------------------------------------------------------------- 1 | /* 2 | * 发布-订阅模式(观察者模式) 3 | * */ 4 | 5 | export const Observer = (function () { 6 | let messages = {}; // 消息队列 7 | 8 | return { 9 | // 订阅消息 10 | subscribe (type, fn) { 11 | // 消息不存在,创建消息执行队列 12 | if (typeof messages[type] === 'undefined') { 13 | messages[type] = [fn]; 14 | } 15 | // 消息存在,将执行动作推进消息执行队列 16 | else { 17 | messages[type].push(fn); 18 | } 19 | }, 20 | // 发布消息 21 | publish (type, args) { 22 | // 如果消息未被注册,返回false 23 | if (!messages[type]) return false; 24 | // 定义消息信息 25 | let events = { 26 | type: type, // 消息类型 27 | args: args || {} // 消息携带数据 28 | }; 29 | for (let i = 0;i < messages[type].length; i++) { 30 | // 执行动作 31 | messages[type][i].call(this, events) 32 | } 33 | }, 34 | // 删除消息 35 | remove (type, fn) { 36 | // 消息队列存在 37 | if (messages[type] instanceof Array) { 38 | // 从最后一个消息动作遍历 39 | let i = messages[type].length - 1; 40 | for (; i >=0; i++) { 41 | // 存在该消息动作,则移除 42 | messages[type][i] === fn && messages[type].splice(i ,1); 43 | } 44 | } 45 | } 46 | } 47 | })(); 48 | 49 | export default Observer; -------------------------------------------------------------------------------- /src/valid/index.js: -------------------------------------------------------------------------------- 1 | // 大陆手机号判断 2 | const isPhone = (val)=>{ 3 | return /^1[3456789]\d{9}$/.test(val); 4 | }; 5 | 6 | /* 7 | * 全中文校验 8 | * */ 9 | function ChineseWordValid (val) { 10 | return /^[\u4E00-\u9FA5]+$/.test(val); 11 | } 12 | 13 | // 英文和数字校验 14 | function wordNumValid(val) { 15 | return /^[0-9A-Za-z]+$/.test(val); 16 | } 17 | 18 | // emoji表情校验 19 | function emojiValid(val) { 20 | const regStr = /[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF][\u200D|\uFE0F]|[\uD83C|\uD83D|\uD83E][\uDC00-\uDFFF]|[0-9|*|#]\uFE0F\u20E3|[0-9|#]\u20E3|[\u203C-\u3299]\uFE0F\u200D|[\u203C-\u3299]\uFE0F|[\u2122-\u2B55]|\u303D|[\A9|\AE]\u3030|\uA9|\uAE|\u3030/ig; 21 | return (regStr.test(val)) 22 | } 23 | 24 | // 邮箱校验 25 | function emailValid (val) { 26 | return /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/.test(val); 27 | } 28 | 29 | /* 30 | * 大陆身份证校验 31 | * */ 32 | const IdentityCodeValid = function (code) { 33 | let city = { 34 | 11:"北京",12:"天津",13:"河北",14:"山西",15:"内蒙古",21:"辽宁",22:"吉林",23:"黑龙江 ",31:"上海",32:"江苏", 35 | 33:"浙江",34:"安徽",35:"福建",36:"江西",37:"山东",41:"河南",42:"湖北 ",43:"湖南",44:"广东",45:"广西",46:"海南", 36 | 50:"重庆",51:"四川",52:"贵州",53:"云南",54:"西藏 ",61:"陕西",62:"甘肃",63:"青海",64:"宁夏",65:"新疆", 37 | 71:"台湾",81:"香港",82:"澳门",91:"国外 " 38 | }; 39 | let tip = ''; 40 | let pass = true; 41 | 42 | if(!code || !/^\d{6}(18|19|20)?\d{2}(0[1-9]|1[012])(0[1-9]|[12]\d|3[01])\d{3}(\d|X)$/i.test(code)){ 43 | tip = "身份证号格式错误"; 44 | pass = false 45 | } else if(!city[code.substr(0,2)]){ 46 | tip = "地址编码错误"; 47 | pass = false 48 | } else{ 49 | // 18位身份证需要验证最后一位校验位 50 | if(code.length == 18){ 51 | code = code.split('') 52 | // ∑(ai×Wi)(mod 11) 53 | // 加权因子 54 | let factor = [ 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 ] 55 | // 校验位 56 | let parity = [ 1, 0, 'X', 9, 8, 7, 6, 5, 4, 3, 2 ] 57 | let sum = 0 58 | let ai = 0 59 | let wi = 0 60 | for (let i = 0; i < 17; i++) 61 | { 62 | ai = code[i] 63 | wi = factor[i] 64 | sum += ai * wi 65 | } 66 | let last = parity[sum % 11]; 67 | if(parity[sum % 11] != code[17]){ 68 | tip = "校验位错误" 69 | pass = false; 70 | } 71 | } 72 | } 73 | return pass; 74 | }; 75 | 76 | export const Valid = { 77 | isPhone, ChineseWordValid, wordNumValid, emojiValid, IdentityCodeValid 78 | }; 79 | 80 | export default { 81 | isPhone, ChineseWordValid, wordNumValid, emojiValid, IdentityCodeValid 82 | } -------------------------------------------------------------------------------- /src/worldCountry.js: -------------------------------------------------------------------------------- 1 | export const Country = [{ 2 | "name": "Andorra", 3 | "cnName": "安道尔", 4 | "abbr": "AD", 5 | "code": "020" 6 | }, { 7 | "name": "United Arab Emirates", 8 | "cnName": "阿联酋", 9 | "abbr": "AE", 10 | "code": "784" 11 | }, { 12 | "name": "Afghanistan", 13 | "cnName": "阿富汗", 14 | "abbr": "AF", 15 | "code": "004" 16 | }, { 17 | "name": "Antigua and Barbuda", 18 | "cnName": "安提瓜和巴布达", 19 | "abbr": "AG", 20 | "code": "028" 21 | }, { 22 | "name": "Anguilla", 23 | "cnName": "安圭拉", 24 | "abbr": "AI", 25 | "code": "660" 26 | }, { 27 | "name": "Albania", 28 | "cnName": "阿尔巴尼亚", 29 | "abbr": "AL", 30 | "code": "008" 31 | }, { 32 | "name": "Armenia", 33 | "cnName": "亚美尼亚", 34 | "abbr": "AM", 35 | "code": "051" 36 | }, { 37 | "name": "Angola", 38 | "cnName": "安哥拉", 39 | "abbr": "AO", 40 | "code": "024" 41 | }, { 42 | "name": "Antarctica", 43 | "cnName": "南极洲", 44 | "abbr": "AQ", 45 | "code": "010" 46 | }, { 47 | "name": "Argentina", 48 | "cnName": "阿根廷", 49 | "abbr": "AR", 50 | "code": "032" 51 | }, { 52 | "name": "American Samoa", 53 | "cnName": "美属萨摩亚", 54 | "abbr": "AS", 55 | "code": "016" 56 | }, { 57 | "name": "Austria", 58 | "cnName": "奥地利", 59 | "abbr": "AT", 60 | "code": "040" 61 | }, { 62 | "name": "Australia", 63 | "cnName": "澳大利亚", 64 | "abbr": "AU", 65 | "code": "036" 66 | }, { 67 | "name": "Aruba", 68 | "cnName": "阿鲁巴", 69 | "abbr": "AW", 70 | "code": "533" 71 | }, { 72 | "name": "Aland Island", 73 | "cnName": "奥兰群岛", 74 | "abbr": "AX", 75 | "code": "248" 76 | }, { 77 | "name": "Azerbaijan", 78 | "cnName": "阿塞拜疆", 79 | "abbr": "AZ", 80 | "code": "031" 81 | }, { 82 | "name": "Bosnia and Herzegovina", 83 | "cnName": "波黑", 84 | "abbr": "BA", 85 | "code": "070" 86 | }, { 87 | "name": "Barbados", 88 | "cnName": "巴巴多斯", 89 | "abbr": "BB", 90 | "code": "052" 91 | }, { 92 | "name": "Bangladesh", 93 | "cnName": "孟加拉", 94 | "abbr": "BD", 95 | "code": "050" 96 | }, { 97 | "name": "Belgium", 98 | "cnName": "比利时", 99 | "abbr": "BE", 100 | "code": "056" 101 | }, { 102 | "name": "Burkina", 103 | "cnName": "布基纳法索", 104 | "abbr": "BF", 105 | "code": "854" 106 | }, { 107 | "name": "Bulgaria", 108 | "cnName": "保加利亚", 109 | "abbr": "BG", 110 | "code": "100" 111 | }, { 112 | "name": "Bahrain", 113 | "cnName": "巴林", 114 | "abbr": "BH", 115 | "code": "048" 116 | }, { 117 | "name": "Burundi", 118 | "cnName": "布隆迪", 119 | "abbr": "BI", 120 | "code": "108" 121 | }, { 122 | "name": "Benin", 123 | "cnName": "贝宁", 124 | "abbr": "BJ", 125 | "code": "204" 126 | }, { 127 | "name": "Saint Barthélemy", 128 | "cnName": "圣巴泰勒米岛", 129 | "abbr": "BL", 130 | "code": "652" 131 | }, { 132 | "name": "Bermuda", 133 | "cnName": "百慕大", 134 | "abbr": "BM", 135 | "code": "060" 136 | }, { 137 | "name": "Brunei", 138 | "cnName": "文莱", 139 | "abbr": "BN", 140 | "code": "096" 141 | }, { 142 | "name": "Bolivia", 143 | "cnName": "玻利维亚", 144 | "abbr": "BO", 145 | "code": "068" 146 | }, { 147 | "name": "Caribbean Netherlands", 148 | "cnName": "荷兰加勒比区", 149 | "abbr": "BQ", 150 | "code": "535" 151 | }, { 152 | "name": "Brazil", 153 | "cnName": "巴西", 154 | "abbr": "BR", 155 | "code": "076" 156 | }, { 157 | "name": "The Bahamas", 158 | "cnName": "巴哈马", 159 | "abbr": "BS", 160 | "code": "044" 161 | }, { 162 | "name": "Bhutan", 163 | "cnName": "不丹", 164 | "abbr": "BT", 165 | "code": "064" 166 | }, { 167 | "name": "Bouvet Island", 168 | "cnName": "布韦岛", 169 | "abbr": "BV", 170 | "code": "074" 171 | }, { 172 | "name": "Botswana", 173 | "cnName": "博茨瓦纳", 174 | "abbr": "BW", 175 | "code": "072" 176 | }, { 177 | "name": "Belarus", 178 | "cnName": "白俄罗斯", 179 | "abbr": "BY", 180 | "code": "112" 181 | }, { 182 | "name": "Belize", 183 | "cnName": "伯利兹", 184 | "abbr": "BZ", 185 | "code": "084" 186 | }, { 187 | "name": "Canada", 188 | "cnName": "加拿大", 189 | "abbr": "CA", 190 | "code": "124" 191 | }, { 192 | "name": "Cocos Keeling Islands", 193 | "cnName": "科科斯群岛", 194 | "abbr": "CC", 195 | "code": "166" 196 | }, { 197 | "name": "Central African Republic", 198 | "cnName": "中非", 199 | "abbr": "CF", 200 | "code": "140" 201 | }, { 202 | "name": "Switzerland", 203 | "cnName": "瑞士", 204 | "abbr": "CH", 205 | "code": "756" 206 | }, { 207 | "name": "Chile", 208 | "cnName": "智利", 209 | "abbr": "CL", 210 | "code": "152" 211 | }, { 212 | "name": "Cameroon", 213 | "cnName": "喀麦隆", 214 | "abbr": "CM", 215 | "code": "120" 216 | }, { 217 | "name": "Colombia", 218 | "cnName": "哥伦比亚", 219 | "abbr": "CO", 220 | "code": "170" 221 | }, { 222 | "name": "Costa Rica", 223 | "cnName": "哥斯达黎加", 224 | "abbr": "CR", 225 | "code": "188" 226 | }, { 227 | "name": "Cuba", 228 | "cnName": "古巴", 229 | "abbr": "CU", 230 | "code": "192" 231 | }, { 232 | "name": "Cape Verde", 233 | "cnName": "佛得角", 234 | "abbr": "CV", 235 | "code": "132" 236 | }, { 237 | "name": "Christmas Island", 238 | "cnName": "圣诞岛", 239 | "abbr": "CX", 240 | "code": "162" 241 | }, { 242 | "name": "Cyprus", 243 | "cnName": "塞浦路斯", 244 | "abbr": "CY", 245 | "code": "196" 246 | }, { 247 | "name": "Czech Republic", 248 | "cnName": "捷克", 249 | "abbr": "CZ", 250 | "code": "203" 251 | }, { 252 | "name": "Germany", 253 | "cnName": "德国", 254 | "abbr": "DE", 255 | "code": "276" 256 | }, { 257 | "name": "Djibouti", 258 | "cnName": "吉布提", 259 | "abbr": "DJ", 260 | "code": "262" 261 | }, { 262 | "name": "Denmark", 263 | "cnName": "丹麦", 264 | "abbr": "DK", 265 | "code": "208" 266 | }, { 267 | "name": "Dominica", 268 | "cnName": "多米尼克", 269 | "abbr": "DM", 270 | "code": "212" 271 | }, { 272 | "name": "Dominican Republic", 273 | "cnName": "多米尼加", 274 | "abbr": "DO", 275 | "code": "214" 276 | }, { 277 | "name": "Algeria", 278 | "cnName": "阿尔及利亚", 279 | "abbr": "DZ", 280 | "code": "012" 281 | }, { 282 | "name": "Ecuador", 283 | "cnName": "厄瓜多尔", 284 | "abbr": "EC", 285 | "code": "218" 286 | }, { 287 | "name": "Estonia", 288 | "cnName": "爱沙尼亚", 289 | "abbr": "EE", 290 | "code": "233" 291 | }, { 292 | "name": "Egypt", 293 | "cnName": "埃及", 294 | "abbr": "EG", 295 | "code": "818" 296 | }, { 297 | "name": "Western Sahara", 298 | "cnName": "西撒哈拉", 299 | "abbr": "EH", 300 | "code": "732" 301 | }, { 302 | "name": "Eritrea", 303 | "cnName": "厄立特里亚", 304 | "abbr": "ER", 305 | "code": "232" 306 | }, { 307 | "name": "Spain", 308 | "cnName": "西班牙", 309 | "abbr": "ES", 310 | "code": "724" 311 | }, { 312 | "name": "Finland", 313 | "cnName": "芬兰", 314 | "abbr": "FI", 315 | "code": "246" 316 | }, { 317 | "name": "Fiji", 318 | "cnName": "斐济群岛", 319 | "abbr": "FJ", 320 | "code": "242" 321 | }, { 322 | "name": "Falkland Islands", 323 | "cnName": "马尔维纳斯群岛( 福克兰)", 324 | "abbr": "FK", 325 | "code": "238" 326 | }, { 327 | "name": "Federated States of Micronesia", 328 | "cnName": "密克罗尼西亚联邦", 329 | "abbr": "FM", 330 | "code": "583" 331 | }, { 332 | "name": "Faroe Islands", 333 | "cnName": "法罗群岛", 334 | "abbr": "FO", 335 | "code": "234" 336 | }, { 337 | "name": "France", 338 | "cnName": "法国", 339 | "abbr": "FR", 340 | "code": "250" 341 | }, { 342 | "name": "Gabon", 343 | "cnName": "加蓬", 344 | "abbr": "GA", 345 | "code": "266" 346 | }, { 347 | "name": "Grenada", 348 | "cnName": "格林纳达", 349 | "abbr": "GD", 350 | "code": "308" 351 | }, { 352 | "name": "Georgia", 353 | "cnName": "格鲁吉亚", 354 | "abbr": "GE", 355 | "code": "268" 356 | }, { 357 | "name": "French Guiana", 358 | "cnName": "法属圭亚那", 359 | "abbr": "GF", 360 | "code": "254" 361 | }, { 362 | "name": "Ghana", 363 | "cnName": "加纳", 364 | "abbr": "GH", 365 | "code": "288" 366 | }, { 367 | "name": "Gibraltar", 368 | "cnName": "直布罗陀", 369 | "abbr": "GI", 370 | "code": "292" 371 | }, { 372 | "name": "Greenland", 373 | "cnName": "格陵兰", 374 | "abbr": "GL", 375 | "code": "304" 376 | }, { 377 | "name": "Guinea", 378 | "cnName": "几内亚", 379 | "abbr": "GN", 380 | "code": "324" 381 | }, { 382 | "name": "Guadeloupe", 383 | "cnName": "瓜德罗普", 384 | "abbr": "GP", 385 | "code": "312" 386 | }, { 387 | "name": "Equatorial Guinea", 388 | "cnName": "赤道几内亚", 389 | "abbr": "GQ", 390 | "code": "226" 391 | }, { 392 | "name": "Greece", 393 | "cnName": "希腊", 394 | "abbr": "GR", 395 | "code": "300" 396 | }, { 397 | "name": "South Georgia and the South Sandwich Islands", 398 | "cnName": "南乔治亚岛和南桑威奇群岛", 399 | "abbr": "GS", 400 | "code": "239" 401 | }, { 402 | "name": "Guatemala", 403 | "cnName": "危地马拉", 404 | "abbr": "GT", 405 | "code": "320" 406 | }, { 407 | "name": "Guam", 408 | "cnName": "关岛", 409 | "abbr": "GU", 410 | "code": "316" 411 | }, { 412 | "name": "Guinea-Bissau", 413 | "cnName": "几内亚比绍", 414 | "abbr": "GW", 415 | "code": "624" 416 | }, { 417 | "name": "Guyana", 418 | "cnName": "圭亚那", 419 | "abbr": "GY", 420 | "code": "328" 421 | }, { 422 | "name": "Hong Kong", 423 | "cnName": "香港", 424 | "abbr": "HK", 425 | "code": "344" 426 | }, { 427 | "name": "Heard Island and McDonald Islands", 428 | "cnName": "赫德岛和麦克唐纳群岛", 429 | "abbr": "HM", 430 | "code": "334" 431 | }, { 432 | "name": "Honduras", 433 | "cnName": "洪都拉斯", 434 | "abbr": "HN", 435 | "code": "340" 436 | }, { 437 | "name": "Croatia", 438 | "cnName": "克罗地亚", 439 | "abbr": "HR", 440 | "code": "191" 441 | }, { 442 | "name": "Haiti", 443 | "cnName": "海地", 444 | "abbr": "HT", 445 | "code": "332" 446 | }, { 447 | "name": "Hungary", 448 | "cnName": "匈牙利", 449 | "abbr": "HU", 450 | "code": "348" 451 | }, { 452 | "name": "Indonesia", 453 | "cnName": "印尼", 454 | "abbr": "ID", 455 | "code": "360" 456 | }, { 457 | "name": "Ireland", 458 | "cnName": "爱尔兰", 459 | "abbr": "IE", 460 | "code": "372" 461 | }, { 462 | "name": "Israel", 463 | "cnName": "以色列", 464 | "abbr": "IL", 465 | "code": "376" 466 | }, { 467 | "name": "Isle of Man", 468 | "cnName": "马恩岛", 469 | "abbr": "IM", 470 | "code": "833" 471 | }, { 472 | "name": "India", 473 | "cnName": "印度", 474 | "abbr": "IN", 475 | "code": "356" 476 | }, { 477 | "name": "British Indian Ocean Territory", 478 | "cnName": "英属印度洋领地", 479 | "abbr": "IO", 480 | "code": "086" 481 | }, { 482 | "name": "Iraq", 483 | "cnName": "伊拉克", 484 | "abbr": "IQ", 485 | "code": "368" 486 | }, { 487 | "name": "Iran", 488 | "cnName": "伊朗", 489 | "abbr": "IR", 490 | "code": "364" 491 | }, { 492 | "name": "Iceland", 493 | "cnName": "冰岛", 494 | "abbr": "IS", 495 | "code": "352" 496 | }, { 497 | "name": "Italy", 498 | "cnName": "意大利", 499 | "abbr": "IT", 500 | "code": "380" 501 | }, { 502 | "name": "Jersey", 503 | "cnName": "泽西岛", 504 | "abbr": "JE", 505 | "code": "832" 506 | }, { 507 | "name": "Jamaica", 508 | "cnName": "牙买加", 509 | "abbr": "JM", 510 | "code": "388" 511 | }, { 512 | "name": "Jordan", 513 | "cnName": "约旦", 514 | "abbr": "JO", 515 | "code": "400" 516 | }, { 517 | "name": "Japan", 518 | "cnName": "日本", 519 | "abbr": "JP", 520 | "code": "392" 521 | }, { 522 | "name": "Cambodia", 523 | "cnName": "柬埔寨", 524 | "abbr": "KH", 525 | "code": "116" 526 | }, { 527 | "name": "Kiribati", 528 | "cnName": "基里巴斯", 529 | "abbr": "KI", 530 | "code": "296" 531 | }, { 532 | "name": "The Comoros", 533 | "cnName": "科摩罗", 534 | "abbr": "KM", 535 | "code": "174" 536 | }, { 537 | "name": "Kuwait", 538 | "cnName": "科威特", 539 | "abbr": "KW", 540 | "code": "414" 541 | }, { 542 | "name": "Cayman Islands", 543 | "cnName": "开曼群岛", 544 | "abbr": "KY", 545 | "code": "136" 546 | }, { 547 | "name": "Lebanon", 548 | "cnName": "黎巴嫩", 549 | "abbr": "LB", 550 | "code": "422" 551 | }, { 552 | "name": "Liechtenstein", 553 | "cnName": "列支敦士登", 554 | "abbr": "LI", 555 | "code": "438" 556 | }, { 557 | "name": "Sri Lanka", 558 | "cnName": "斯里兰卡", 559 | "abbr": "LK", 560 | "code": "144" 561 | }, { 562 | "name": "Liberia", 563 | "cnName": "利比里亚", 564 | "abbr": "LR", 565 | "code": "430" 566 | }, { 567 | "name": "Lesotho", 568 | "cnName": "莱索托", 569 | "abbr": "LS", 570 | "code": "426" 571 | }, { 572 | "name": "Lithuania", 573 | "cnName": "立陶宛", 574 | "abbr": "LT", 575 | "code": "440" 576 | }, { 577 | "name": "Luxembourg", 578 | "cnName": "卢森堡", 579 | "abbr": "LU", 580 | "code": "442" 581 | }, { 582 | "name": "Latvia", 583 | "cnName": "拉脱维亚", 584 | "abbr": "LV", 585 | "code": "428" 586 | }, { 587 | "name": "Libya", 588 | "cnName": "利比亚", 589 | "abbr": "LY", 590 | "code": "434" 591 | }, { 592 | "name": "Morocco", 593 | "cnName": "摩洛哥", 594 | "abbr": "MA", 595 | "code": "504" 596 | }, { 597 | "name": "Monaco", 598 | "cnName": "摩纳哥", 599 | "abbr": "MC", 600 | "code": "492" 601 | }, { 602 | "name": "Moldova", 603 | "cnName": "摩尔多瓦", 604 | "abbr": "MD", 605 | "code": "498" 606 | }, { 607 | "name": "Montenegro", 608 | "cnName": "黑山", 609 | "abbr": "ME", 610 | "code": "499" 611 | }, { 612 | "name": "Saint Martin", 613 | "cnName": "法属圣马丁", 614 | "abbr": "MF", 615 | "code": "663" 616 | }, { 617 | "name": "Madagascar", 618 | "cnName": "马达加斯加", 619 | "abbr": "MG", 620 | "code": "450" 621 | }, { 622 | "name": "Marshall islands", 623 | "cnName": "马绍尔群岛", 624 | "abbr": "MH", 625 | "code": "584" 626 | }, { 627 | "name": "Republic of Macedonia", 628 | "cnName": "马其顿", 629 | "abbr": "MK", 630 | "code": "807" 631 | }, { 632 | "name": "Mali", 633 | "cnName": "马里", 634 | "abbr": "ML", 635 | "code": "466" 636 | }, { 637 | "name": "Myanmar", 638 | "cnName": "缅甸", 639 | "abbr": "MM", 640 | "code": "104" 641 | }, { 642 | "name": "Macao", 643 | "cnName": "澳门", 644 | "abbr": "MO", 645 | "code": "446" 646 | }, { 647 | "name": "Martinique", 648 | "cnName": "马提尼克", 649 | "abbr": "MQ", 650 | "code": "474" 651 | }, { 652 | "name": "Mauritania", 653 | "cnName": "毛里塔尼亚", 654 | "abbr": "MR", 655 | "code": "478" 656 | }, { 657 | "name": "Montserrat", 658 | "cnName": "蒙塞拉特岛", 659 | "abbr": "MS", 660 | "code": "500" 661 | }, { 662 | "name": "Malta", 663 | "cnName": "马耳他", 664 | "abbr": "MT", 665 | "code": "470" 666 | }, { 667 | "name": "Maldives", 668 | "cnName": "马尔代夫", 669 | "abbr": "MV", 670 | "code": "462" 671 | }, { 672 | "name": "Malawi", 673 | "cnName": "马拉维", 674 | "abbr": "MW", 675 | "code": "454" 676 | }, { 677 | "name": "Mexico", 678 | "cnName": "墨西哥", 679 | "abbr": "MX", 680 | "code": "484" 681 | }, { 682 | "name": "Malaysia", 683 | "cnName": "马来西亚", 684 | "abbr": "MY", 685 | "code": "458" 686 | }, { 687 | "name": "Namibia", 688 | "cnName": "纳米比亚", 689 | "abbr": "NA", 690 | "code": "516" 691 | }, { 692 | "name": "Niger", 693 | "cnName": "尼日尔", 694 | "abbr": "NE", 695 | "code": "562" 696 | }, { 697 | "name": "Norfolk Island", 698 | "cnName": "诺福克岛", 699 | "abbr": "NF", 700 | "code": "574" 701 | }, { 702 | "name": "Nigeria", 703 | "cnName": "尼日利亚", 704 | "abbr": "NG", 705 | "code": "566" 706 | }, { 707 | "name": "Nicaragua", 708 | "cnName": "尼加拉瓜", 709 | "abbr": "NI", 710 | "code": "558" 711 | }, { 712 | "name": "Netherlands", 713 | "cnName": "荷兰", 714 | "abbr": "NL", 715 | "code": "528" 716 | }, { 717 | "name": "Norway", 718 | "cnName": "挪威", 719 | "abbr": "NO", 720 | "code": "578" 721 | }, { 722 | "name": "Nepal", 723 | "cnName": "尼泊尔", 724 | "abbr": "NP", 725 | "code": "524" 726 | }, { 727 | "name": "Nauru", 728 | "cnName": "瑙鲁", 729 | "abbr": "NR", 730 | "code": "520" 731 | }, { 732 | "name": "Oman", 733 | "cnName": "阿曼", 734 | "abbr": "OM", 735 | "code": "512" 736 | }, { 737 | "name": "Panama", 738 | "cnName": "巴拿马", 739 | "abbr": "PA", 740 | "code": "591" 741 | }, { 742 | "name": "Peru", 743 | "cnName": "秘鲁", 744 | "abbr": "PE", 745 | "code": "604" 746 | }, { 747 | "name": "French polynesia", 748 | "cnName": "法属波利尼西亚", 749 | "abbr": "PF", 750 | "code": "258" 751 | }, { 752 | "name": "Papua New Guinea", 753 | "cnName": "巴布亚新几内亚", 754 | "abbr": "PG", 755 | "code": "598" 756 | }, { 757 | "name": "The Philippines", 758 | "cnName": "菲律宾", 759 | "abbr": "PH", 760 | "code": "608" 761 | }, { 762 | "name": "Pakistan", 763 | "cnName": "巴基斯坦", 764 | "abbr": "PK", 765 | "code": "586" 766 | }, { 767 | "name": "Poland", 768 | "cnName": "波兰", 769 | "abbr": "PL", 770 | "code": "616" 771 | }, { 772 | "name": "Pitcairn Islands", 773 | "cnName": "皮特凯恩群岛", 774 | "abbr": "PN", 775 | "code": "612" 776 | }, { 777 | "name": "Puerto Rico", 778 | "cnName": "波多黎各", 779 | "abbr": "PR", 780 | "code": "630" 781 | }, { 782 | "name": "Palestinian territories", 783 | "cnName": "巴勒斯坦", 784 | "abbr": "PS", 785 | "code": "275" 786 | }, { 787 | "name": "Palau", 788 | "cnName": "帕劳", 789 | "abbr": "PW", 790 | "code": "585" 791 | }, { 792 | "name": "Paraguay", 793 | "cnName": "巴拉圭", 794 | "abbr": "PY", 795 | "code": "600" 796 | }, { 797 | "name": "Qatar", 798 | "cnName": "卡塔尔", 799 | "abbr": "QA", 800 | "code": "634" 801 | }, { 802 | "name": "Réunion", 803 | "cnName": "留尼汪", 804 | "abbr": "RE", 805 | "code": "638" 806 | }, { 807 | "name": "Romania", 808 | "cnName": "罗马尼亚", 809 | "abbr": "RO", 810 | "code": "642" 811 | }, { 812 | "name": "Serbia", 813 | "cnName": "塞尔维亚", 814 | "abbr": "RS", 815 | "code": "688" 816 | }, { 817 | "name": "Russia", 818 | "cnName": "俄罗斯", 819 | "abbr": "RU", 820 | "code": "643" 821 | }, { 822 | "name": "Rwanda", 823 | "cnName": "卢旺达", 824 | "abbr": "RW", 825 | "code": "646" 826 | }, { 827 | "name": "Solomon Islands", 828 | "cnName": "所罗门群岛", 829 | "abbr": "SB", 830 | "code": "090" 831 | }, { 832 | "name": "Seychelles", 833 | "cnName": "塞舌尔", 834 | "abbr": "SC", 835 | "code": "690" 836 | }, { 837 | "name": "Sudan", 838 | "cnName": "苏丹", 839 | "abbr": "SD", 840 | "code": "729" 841 | }, { 842 | "name": "Sweden", 843 | "cnName": "瑞典", 844 | "abbr": "SE", 845 | "code": "752" 846 | }, { 847 | "name": "Singapore", 848 | "cnName": "新加坡", 849 | "abbr": "SG", 850 | "code": "702" 851 | }, { 852 | "name": "Slovenia", 853 | "cnName": "斯洛文尼亚", 854 | "abbr": "SI", 855 | "code": "705" 856 | }, { 857 | "name": "Country data SJM Svalbard", 858 | "cnName": "斯瓦尔巴群岛和 扬马延岛", 859 | "abbr": "SJ", 860 | "code": "744" 861 | }, { 862 | "name": "Slovakia", 863 | "cnName": "斯洛伐克", 864 | "abbr": "SK", 865 | "code": "703" 866 | }, { 867 | "name": "Sierra Leone", 868 | "cnName": "塞拉利昂", 869 | "abbr": "SL", 870 | "code": "694" 871 | }, { 872 | "name": "San Marino", 873 | "cnName": "圣马力诺", 874 | "abbr": "SM", 875 | "code": "674" 876 | }, { 877 | "name": "Senegal", 878 | "cnName": "塞内加尔", 879 | "abbr": "SN", 880 | "code": "686" 881 | }, { 882 | "name": "Somalia", 883 | "cnName": "索马里", 884 | "abbr": "SO", 885 | "code": "706" 886 | }, { 887 | "name": "Suriname", 888 | "cnName": "苏里南", 889 | "abbr": "SR", 890 | "code": "740" 891 | }, { 892 | "name": "South Sudan", 893 | "cnName": "南苏丹", 894 | "abbr": "SS", 895 | "code": "728" 896 | }, { 897 | "name": "Sao Tome and Principe", 898 | "cnName": "圣多美和普林西比", 899 | "abbr": "ST", 900 | "code": "678" 901 | }, { 902 | "name": "El Salvador", 903 | "cnName": "萨尔瓦多", 904 | "abbr": "SV", 905 | "code": "222" 906 | }, { 907 | "name": "Syria", 908 | "cnName": "叙利亚", 909 | "abbr": "SY", 910 | "code": "760" 911 | }, { 912 | "name": "Swaziland", 913 | "cnName": "斯威士兰", 914 | "abbr": "SZ", 915 | "code": "748" 916 | }, { 917 | "name": "Turks and Caicos Islands", 918 | "cnName": "特克斯和凯科斯群岛", 919 | "abbr": "TC", 920 | "code": "796" 921 | }, { 922 | "name": "Chad", 923 | "cnName": "乍得", 924 | "abbr": "TD", 925 | "code": "148" 926 | }, { 927 | "name": "Togo", 928 | "cnName": "多哥", 929 | "abbr": "TG", 930 | "code": "768" 931 | }, { 932 | "name": "Thailand", 933 | "cnName": "泰国", 934 | "abbr": "TH", 935 | "code": "764" 936 | }, { 937 | "name": "Tokelau", 938 | "cnName": "托克劳", 939 | "abbr": "TK", 940 | "code": "772" 941 | }, { 942 | "name": "East Timor", 943 | "cnName": "东帝汶", 944 | "abbr": "TL", 945 | "code": "626" 946 | }, { 947 | "name": "Tunisia", 948 | "cnName": "突尼斯", 949 | "abbr": "TN", 950 | "code": "788" 951 | }, { 952 | "name": "Tonga", 953 | "cnName": "汤加", 954 | "abbr": "TO", 955 | "code": "776" 956 | }, { 957 | "name": "Turkey", 958 | "cnName": "土耳其", 959 | "abbr": "TR", 960 | "code": "792" 961 | }, { 962 | "name": "Tuvalu", 963 | "cnName": "图瓦卢", 964 | "abbr": "TV", 965 | "code": "798" 966 | }, { 967 | "name": "Tanzania", 968 | "cnName": "坦桑尼亚", 969 | "abbr": "TZ", 970 | "code": "834" 971 | }, { 972 | "name": "Ukraine", 973 | "cnName": "乌克兰", 974 | "abbr": "UA", 975 | "code": "804" 976 | }, { 977 | "name": "Uganda", 978 | "cnName": "乌干达", 979 | "abbr": "UG", 980 | "code": "800" 981 | }, { 982 | "name": "United States", 983 | "cnName": "美国", 984 | "abbr": "US", 985 | "code": "840" 986 | }, { 987 | "name": "Uruguay", 988 | "cnName": "乌拉圭", 989 | "abbr": "UY", 990 | "code": "858" 991 | }, { 992 | "name": "Vatican City", 993 | "cnName": "梵蒂冈", 994 | "abbr": "VA", 995 | "code": "336" 996 | }, { 997 | "name": "Venezuela", 998 | "cnName": "委内瑞拉", 999 | "abbr": "VE", 1000 | "code": "862" 1001 | }, { 1002 | "name": "British Virgin Islands", 1003 | "cnName": "英属维尔京群岛", 1004 | "abbr": "VG", 1005 | "code": "092" 1006 | }, { 1007 | "name": "United States Virgin Islands", 1008 | "cnName": "美属维尔京群岛", 1009 | "abbr": "VI", 1010 | "code": "850" 1011 | }, { 1012 | "name": "Vietnam", 1013 | "cnName": "越南", 1014 | "abbr": "VN", 1015 | "code": "704" 1016 | }, { 1017 | "name": "Wallis and Futuna", 1018 | "cnName": "瓦利斯和富图纳", 1019 | "abbr": "WF", 1020 | "code": "876" 1021 | }, { 1022 | "name": "Samoa", 1023 | "cnName": "萨摩亚", 1024 | "abbr": "WS", 1025 | "code": "882" 1026 | }, { 1027 | "name": "Yemen", 1028 | "cnName": "也门", 1029 | "abbr": "YE", 1030 | "code": "887" 1031 | }, { 1032 | "name": "Mayotte", 1033 | "cnName": "马约特", 1034 | "abbr": "YT", 1035 | "code": "175" 1036 | }, { 1037 | "name": "South Africa", 1038 | "cnName": "南非", 1039 | "abbr": "ZA", 1040 | "code": "710" 1041 | }, { 1042 | "name": "Zambia", 1043 | "cnName": "赞比亚", 1044 | "abbr": "ZM", 1045 | "code": "894" 1046 | }, { 1047 | "name": "Zimbabwe", 1048 | "cnName": "津巴布韦", 1049 | "abbr": "ZW", 1050 | "code": "716" 1051 | }, { 1052 | "name": "China", 1053 | "cnName": "中国", 1054 | "abbr": "CN", 1055 | "code": "156" 1056 | }, { 1057 | "name": "Republic of the Congo", 1058 | "cnName": "刚果(布)", 1059 | "abbr": "CG", 1060 | "code": "178" 1061 | }, { 1062 | "name": "Democratic Republic of the Congo", 1063 | "cnName": "刚果(金)", 1064 | "abbr": "CD", 1065 | "code": "180" 1066 | }, { 1067 | "name": "Mozambique", 1068 | "cnName": "莫桑比克", 1069 | "abbr": "MZ", 1070 | "code": "508" 1071 | }, { 1072 | "name": "Guernsey", 1073 | "cnName": "根西岛", 1074 | "abbr": "GG", 1075 | "code": "831" 1076 | }, { 1077 | "name": "Gambia", 1078 | "cnName": "冈比亚", 1079 | "abbr": "GM", 1080 | "code": "270" 1081 | }, { 1082 | "name": "Northern Mariana Islands", 1083 | "cnName": "北马里亚纳群岛", 1084 | "abbr": "MP", 1085 | "code": "580" 1086 | }, { 1087 | "name": "Ethiopia", 1088 | "cnName": "埃塞俄比亚", 1089 | "abbr": "ET", 1090 | "code": "231" 1091 | }, { 1092 | "name": "New Caledonia", 1093 | "cnName": "新喀里多尼亚", 1094 | "abbr": "NC", 1095 | "code": "540" 1096 | }, { 1097 | "name": "Vanuatu", 1098 | "cnName": "瓦努阿图", 1099 | "abbr": "VU", 1100 | "code": "548" 1101 | }, { 1102 | "name": "French Southern Territories", 1103 | "cnName": "法属南部领地", 1104 | "abbr": "TF", 1105 | "code": "260" 1106 | }, { 1107 | "name": "Niue", 1108 | "cnName": "纽埃", 1109 | "abbr": "NU", 1110 | "code": "570" 1111 | }, { 1112 | "name": "United States Minor Outlying Islands", 1113 | "cnName": "美国本土外小岛屿", 1114 | "abbr": "UM", 1115 | "code": "581" 1116 | }, { 1117 | "name": "Cook Islands", 1118 | "cnName": "库克群岛", 1119 | "abbr": "CK", 1120 | "code": "184" 1121 | }, { 1122 | "name": "United Kingdom", 1123 | "cnName": "英国", 1124 | "abbr": "GB", 1125 | "code": "826" 1126 | }, { 1127 | "name": "Trinidad and Tobago", 1128 | "cnName": "特立尼达和多巴哥", 1129 | "abbr": "TT", 1130 | "code": "780" 1131 | }, { 1132 | "name": "St. Vincent and the Grenadines", 1133 | "cnName": "圣文森特和格林纳丁斯", 1134 | "abbr": "VC", 1135 | "code": "670" 1136 | }, { 1137 | "name": "Taiwan", 1138 | "cnName": "中国台湾", 1139 | "abbr": "TW", 1140 | "code": "158" 1141 | }, { 1142 | "name": "New Zealand", 1143 | "cnName": "新西兰", 1144 | "abbr": "NZ", 1145 | "code": "554" 1146 | }, { 1147 | "name": "Saudi Arabia", 1148 | "cnName": "沙特阿拉伯", 1149 | "abbr": "SA", 1150 | "code": "682" 1151 | }, { 1152 | "name": "Laos", 1153 | "cnName": "老挝", 1154 | "abbr": "LA", 1155 | "code": "418" 1156 | }, { 1157 | "name": "North Korea", 1158 | "cnName": "朝鲜 北朝鲜", 1159 | "abbr": "KP", 1160 | "code": "408" 1161 | }, { 1162 | "name": "South Korea", 1163 | "cnName": "韩国 南朝鲜", 1164 | "abbr": "KR", 1165 | "code": "410" 1166 | }, { 1167 | "name": "Portugal", 1168 | "cnName": "葡萄牙", 1169 | "abbr": "PT", 1170 | "code": "620" 1171 | }, { 1172 | "name": "Kyrgyzstan", 1173 | "cnName": "吉尔吉斯斯坦", 1174 | "abbr": "KG", 1175 | "code": "417" 1176 | }, { 1177 | "name": "Kazakhstan", 1178 | "cnName": "哈萨克斯坦", 1179 | "abbr": "KZ", 1180 | "code": "398" 1181 | }, { 1182 | "name": "Tajikistan", 1183 | "cnName": "塔吉克斯坦", 1184 | "abbr": "TJ", 1185 | "code": "762" 1186 | }, { 1187 | "name": "Turkmenistan", 1188 | "cnName": "土库曼斯坦", 1189 | "abbr": "TM", 1190 | "code": "795" 1191 | }, { 1192 | "name": "Uzbekistan", 1193 | "cnName": "乌兹别克斯坦", 1194 | "abbr": "UZ", 1195 | "code": "860" 1196 | }, { 1197 | "name": "St. Kitts and Nevis", 1198 | "cnName": "圣基茨和尼维斯", 1199 | "abbr": "KN", 1200 | "code": "659" 1201 | }, { 1202 | "name": "Saint-Pierre and Miquelon", 1203 | "cnName": "圣皮埃尔和密克隆", 1204 | "abbr": "PM", 1205 | "code": "666" 1206 | }, { 1207 | "name": "St. Helena and Dependencies", 1208 | "cnName": "圣赫勒拿", 1209 | "abbr": "SH", 1210 | "code": "654" 1211 | }, { 1212 | "name": "St. Lucia", 1213 | "cnName": "圣卢西亚", 1214 | "abbr": "LC", 1215 | "code": "662" 1216 | }, { 1217 | "name": "Mauritius", 1218 | "cnName": "毛里求斯", 1219 | "abbr": "MU", 1220 | "code": "480" 1221 | }, { 1222 | "name": "C?te d'Ivoire", 1223 | "cnName": "科特迪瓦", 1224 | "abbr": "CI", 1225 | "code": "384" 1226 | }, { 1227 | "name": "Kenya", 1228 | "cnName": "肯尼亚", 1229 | "abbr": "KE", 1230 | "code": "404" 1231 | }, { 1232 | "name": "Mongolia", 1233 | "cnName": "蒙古国 蒙古", 1234 | "abbr": "MN", 1235 | "code": "496" 1236 | }]; 1237 | 1238 | export default Country; 1239 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const webpack = require('webpack'); 3 | const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); 4 | const CleanWebpackPlugin = require("clean-webpack-plugin"); 5 | 6 | 7 | module.exports = { 8 | mode: 'production', 9 | entry: './src/index.js', 10 | output: { 11 | path: path.resolve(__dirname, 'dist'), 12 | // libraryTarget: 'umd', // 采用通用模块定义 13 | // libraryExport: 'default', // 兼容 ES6(ES2015) 的模块系统、CommonJS 和 AMD 模块规范 14 | // library: ['Utils'], 15 | filename: 'utils.min.js', 16 | // globalObject: 'this', // 定义全局变量,兼容node和浏览器运行,避免出现"window is not defined"的情况 17 | 18 | library: 'Utils', 19 | globalObject: 'this', 20 | libraryExport: 'default', 21 | libraryTarget: 'umd' 22 | }, 23 | devtool: "#source-map", 24 | module: { 25 | rules: [ 26 | { 27 | test: /\.js$/, 28 | loader: 'babel-loader' 29 | } 30 | ] 31 | }, 32 | plugins: [ 33 | new UglifyJsPlugin({ 34 | sourceMap: true, 35 | uglifyOptions: { 36 | warnings: false, 37 | compress: { 38 | drop_console: true // 删除console语句 39 | }, 40 | output: { 41 | // comments: false, 42 | beautify: false 43 | } 44 | }, 45 | parallel: true 46 | }) 47 | 48 | ] 49 | }; -------------------------------------------------------------------------------- /webpack.dev.config.js: -------------------------------------------------------------------------------- 1 | const HOST = "0.0.0.0"; 2 | const PORT = 3200; 3 | const path = require('path'); 4 | const portfinder = require("portfinder"); 5 | 6 | let devWebpackConfig = { 7 | mode: 'development', 8 | entry: { 9 | app: path.join(__dirname, 'dev', 'index.js') 10 | }, 11 | output: { 12 | path: path.join(__dirname, 'dev'), 13 | filename: 'bundle.js' 14 | // globalObject: 'this' // 兼容node和浏览器运行,避免window is not undefined情况 15 | }, 16 | module: { 17 | rules: [ 18 | { 19 | test: /\.js$/, 20 | loader: 'babel-loader' 21 | } 22 | ] 23 | }, 24 | devServer: { 25 | contentBase: path.join(__dirname, "dev"), 26 | clientLogLevel: 'warning', 27 | hot: true, 28 | compress: true, 29 | host: HOST, 30 | port: PORT, 31 | open: false 32 | }, 33 | devtool: "#inline-source-map" 34 | }; 35 | 36 | module.exports = new Promise((resolve, reject) => { 37 | portfinder.basePort = PORT; 38 | portfinder.getPort((err, port) => { 39 | if (err) reject(err); 40 | else { 41 | devWebpackConfig.devServer.port = port; 42 | resolve(devWebpackConfig); 43 | } 44 | }) 45 | }); --------------------------------------------------------------------------------