├── 禁止调试js
├── 滚动条.md
├── app.js
├── utils.js
└── README.md
/禁止调试js:
--------------------------------------------------------------------------------
1 | eval(function(c,g,a,b,d,e){d=String;if(!"".replace(/^/,String)){for(;a--;)e[a]=b[a]||a;b=[function(f){return e[f]}];d=function(){return"\\w+"};a=1}for(;a--;)b[a]&&(c=c.replace(new RegExp("\\b"+d(a)+"\\b","g"),b[a]));return c}('(()=>{1 0(){2(()=>{3("4")()},5)}6{0()}7(8){}})();',9,9,"block function setInterval Function debugger 50 try catch err".split(" "),0,{}));
2 |
--------------------------------------------------------------------------------
/滚动条.md:
--------------------------------------------------------------------------------
1 | IE滚动条
2 |
3 | html, body{
4 | scrollbar-face-color:#F3F3F3; /*面子*/
5 | scrollbar-arrow-color:#C0C0C0; /*箭头*/
6 | scrollbar-3dlight-color:#C0C0C0; /*最外左*/
7 | scrollbar-highlight-color:#FFFFFF; /*左二*/
8 | scrollbar-shadow-color:#FFFFFF; /*右二*/
9 | scrollbar-darkshadow-color:#C0C0C0; /*右一*/
10 | scrollbar-track-color:#F3F3F3; /*滑道*/
11 | }
12 |
13 | Chrome滚动条
14 |
15 | ::-webkit-scrollbar,.protocol-content::-webkit-scrollbar {
16 | width: 12px;/*滚动条粗细*/
17 | height: 12px
18 | }
19 |
20 | ::-webkit-scrollbar-track,.protocol-content::-webkit-scrollbar-track {
21 | -webkit-box-shadow: inset 0 0 2px rgba(0,0,0,.3);
22 | background: orange; /*滑道颜色*/
23 | border-radius: 5px; /*滑道的圆滑度*/
24 | }
25 |
26 | ::-webkit-scrollbar-thumb,.protocol-content::-webkit-scrollbar-thumb {
27 | background: green; /*滑块颜色*/
28 | border-radius: 5px /*滑块圆滑度*/
29 | }
30 |
31 | ::-webkit-scrollbar-thumb:hover,.protocol-content::-webkit-scrollbar-thumb:hover {
32 | background: gray; /*滑块上浮*/
33 | }
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/app.js:
--------------------------------------------------------------------------------
1 | const cheerio = require('cheerio');
2 | const superagent = require('superagent');
3 | const Koa = require('koa')
4 | const router = require('koa-router')()
5 | const cors = require('koa-cors')
6 | const app = new Koa()
7 |
8 | // app.use(async (ctx, next) => {
9 | // if (ctx.request.path === '/') {
10 | // ctx.response.body = '
index page
';
11 | // } else {
12 | // await next();
13 | // }
14 | // });
15 | // app.use(async (ctx, next) => {
16 | // if (ctx.request.path === '/home') {
17 | // ctx.response.body = 'home page
';
18 | // } else {
19 | // await next();
20 | // }
21 | // });
22 | // app.use(async (ctx, next) => {
23 | // if (ctx.request.path === '/404') {
24 | // ctx.response.body = '404 Not Found
';
25 | // } else {
26 | // await next();
27 | // }
28 | // });
29 |
30 |
31 | // var fs = require('fs');
32 | router
33 | .get('/dfvideos/:id', async (ctx, next) => {
34 | let result = await getDfVideo(ctx.params.id)
35 | ctx.body = result
36 | next()
37 | })
38 | function getDfVideo (id) {
39 | return new Promise((resolve, reject) => {
40 | superagent.get(`https://video.eastday.com/a/${id}.html`).end((err, response) => {
41 | if (err) {
42 | reject(err);
43 | }
44 | var $ = cheerio.load(response.text);
45 | $('script').filter((i, v) => {
46 | if (i == 4) {
47 | var oData = $(v).html().replace(/^\s*/g, '');
48 | eval(oData);
49 | var res = {
50 | typename: typename,
51 | d_source: d_source,
52 | d_dfhid: d_dfhid,
53 | mp4long: mp4long,
54 | typechinesename: typechinesename,
55 | ymd: ymd,
56 | uk_for_tbtj: uk_for_tbtj,
57 | tbtj: tbtj
58 | };
59 | resolve(JSON.stringify(res))
60 | }
61 | })
62 | })
63 | })
64 | }
65 | router.get('/feiyan', async (ctx, next) => {
66 | let result = await getDxyData()
67 | ctx.body = result
68 | next()
69 | })
70 | function getDxyData () {
71 | return new Promise((resolve, reject) => {
72 | superagent.get('https://ncov.dxy.cn/ncovh5/view/pneumonia').end((err, response) => {
73 | if (err) {
74 | console.log(err)
75 | resolve(err);
76 | }
77 | var $ = cheerio.load(response.text);
78 | let result = {}
79 | $('script').filter((i, v) => {
80 | if ($(v).html().indexOf('try { window.getAreaStat') !== -1) {
81 | var getAreaStat = $(v).html().replace(/^\s*/g, '').slice(27).slice(0, -11);
82 | result = getAreaStat
83 | }
84 | })
85 | resolve(result)
86 | })
87 | })
88 | }
89 |
90 | // router
91 | // .get('/:id', async (ctx, next) => {
92 | // let result = await getData(ctx.params.id)
93 | // ctx.body = result
94 | // next()
95 | // })
96 | // function getData (id) {
97 | // return new Promise((resolve, reject) => {
98 | // superagent.get(`http://www.toutiao.com/${id}/`).end((err, response) => {
99 | // if (err) {
100 | // console.log(err)
101 | // resolve(err);
102 | // }
103 | // var $ = cheerio.load(response.text);
104 | // $('script').filter((i, v) => {
105 | // if (i == 6) {
106 | // var oData = $(v).html().replace(/^\s*/g, '');
107 | // eval(oData);
108 | // var res = BASE_DATA;
109 | // // fs.writeFileSync('toutiao-data.js', JSON.stringify(res));
110 | // // ctx.type = ''
111 | // resolve(JSON.stringify(res))
112 | // }
113 | // })
114 | // })
115 | // })
116 |
117 | // }
118 | app.use(router.routes())
119 | app.use(cors())
120 | app.listen(5566, () => {
121 | console.log('server is running at http://localhost:5566')
122 | })
123 |
--------------------------------------------------------------------------------
/utils.js:
--------------------------------------------------------------------------------
1 | export const ua = navigator.userAgent.toLowerCase();
2 | // 是否是IE浏览器
3 | export const isIe = () => {
4 | return ua.indexOf("MSIE") >= 0 ? true : false;
5 | };
6 | // 是否是微信浏览器
7 | export const isWeiXin = () => {
8 | return ua.match(/microMessenger/i) == "micromessenger";
9 | };
10 | // 是否是移动端
11 | export const isMobile = () => {
12 | return /android|webos|iphone|ipod|balckberry/i.test(ua);
13 | };
14 | // 是否是QQ浏览器
15 | export const isQQBrowser = () => {
16 | return !!ua.match(/mqqbrowser|qzone|qqbrowser|qbwebviewtype/i);
17 | };
18 | // 是否是爬虫
19 | export const isSpider = () => {
20 | return /adsbot|googlebot|bingbot|msnbot|yandexbot|baidubot|robot|careerbot|seznambot|bot|baiduspider|jikespider|symantecspider|scannerlwebcrawler|crawler|360spider|sosospider|sogou web sprider|sogou orion spider/.test(
21 | ua
22 | );
23 | };
24 | export const isEmail = (t) => {
25 | return /^(\w-*\.*)+@(\w-?)+(\.\w{2,})+$/.test(t);
26 | }
27 | export const isAlipay = () => {
28 | return -1 !== ua.indexOf("alipay");
29 | }
30 | // export const copyTextToClipboard = (t, e) => {
31 | // let n = document.querySelector("#copy-input");
32 | // n ||
33 | // ((n = document.createElement("input")),
34 | // (n.id = "copy-input"),
35 | // (n.readOnly = "readOnly"),
36 | // (n.style.position = "fixed"),
37 | // (n.style.left = "-1000px"),
38 | // (n.style.zIndex = "-1000"),
39 | // document.body.appendChild(n)),
40 | // (n.value = t),
41 | // (function (t, e, n) {
42 | // if (t.createTextRange) {
43 | // const o = t.createTextRange();
44 | // o.collapse(!0),
45 | // o.moveStart("character", e),
46 | // o.moveEnd("character", n - e),
47 | // o.select();
48 | // } else t.setSelectionRange(e, n), t.focus();
49 | // })(n, 0, t.length);
50 | // try {
51 | // document.execCommand("copy");
52 | // e && e();
53 | // } catch (t) {
54 | // console.log("Oops, unable to copy");
55 | // }
56 | // }
57 | export const isHtmlXss = (t) => {
58 | return t.match(/<[^>]+>/g);
59 | }
60 | // 去除html标签
61 | export const removeHtmltag = (str) => {
62 | return str.replace(/<[^>]+>/g, "");
63 | };
64 | // 获取url参数
65 | export const getQueryString = (name) => {
66 | const reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
67 | const search = window.location.search.split("?")[1] || "";
68 | const r = search.match(reg) || [];
69 | return r[2];
70 | };
71 | // 生成uuid
72 | export const uuid = (len) => {
73 | let chars =
74 | "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".split("");
75 | let uuid = [],
76 | i;
77 | let radix = 16;
78 | if (len) {
79 | for (i = 0; i < len; i++) uuid[i] = chars[0 | (Math.random() * radix)];
80 | } else {
81 | let r;
82 | uuid[8] = uuid[13] = uuid[18] = uuid[23] = "-";
83 | uuid[14] = "4";
84 | for (i = 0; i < 36; i++) {
85 | if (!uuid[i]) {
86 | r = 0 | (Math.random() * 16);
87 | uuid[i] = chars[i == 19 ? (r & 0x3) | 0x8 : r];
88 | }
89 | }
90 | }
91 | return uuid.join("");
92 | };
93 | // 动态引入js
94 | export const injectScript = (src) => {
95 | const s = document.createElement("script");
96 | s.type = "text/javascript";
97 | s.async = true;
98 | s.src = src;
99 | const t = document.getElementsByTagName("script")[0];
100 | t.parentNode.insertBefore(s, t);
101 | };
102 | // 根据url地址下载
103 | export const download = (url) => {
104 | var isChrome = navigator.userAgent.toLowerCase().indexOf("chrome") > -1;
105 | var isSafari = navigator.userAgent.toLowerCase().indexOf("safari") > -1;
106 | if (isChrome || isSafari) {
107 | var link = document.createElement("a");
108 | link.href = url;
109 | if (link.download !== undefined) {
110 | var fileName = url.substring(url.lastIndexOf("/") + 1, url.length);
111 | link.download = fileName;
112 | }
113 | if (document.createEvent) {
114 | var e = document.createEvent("MouseEvents");
115 | e.initEvent("click", true, true);
116 | link.dispatchEvent(e);
117 | return true;
118 | }
119 | }
120 | if (url.indexOf("?") === -1) {
121 | url += "?download";
122 | }
123 | window.open(url, "_self");
124 | return true;
125 | };
126 | // el是否包含某个class
127 | export const hasClass = (el, className) => {
128 | let reg = new RegExp("(^|\\s)" + className + "(\\s|$)");
129 | return reg.test(el.className);
130 | };
131 | // el添加某个class
132 | export const addClass = (el, className) => {
133 | if (hasClass(el, className)) {
134 | return;
135 | }
136 | let newClass = el.className.split(" ");
137 | newClass.push(className);
138 | el.className = newClass.join(" ");
139 | };
140 | // el去除某个class
141 | export const removeClass = (el, className) => {
142 | if (!hasClass(el, className)) {
143 | return;
144 | }
145 | let reg = new RegExp("(^|\\s)" + className + "(\\s|$)", "g");
146 | el.className = el.className.replace(reg, " ");
147 | };
148 | // 获取滚动的坐标
149 | export const getScrollPosition = (el = window) => ({
150 | x: el.pageXOffset !== undefined ? el.pageXOffset : el.scrollLeft,
151 | y: el.pageYOffset !== undefined ? el.pageYOffset : el.scrollTop,
152 | });
153 | // 滚动到顶部
154 | export const scrollToTop = () => {
155 | const c = document.documentElement.scrollTop || document.body.scrollTop;
156 | if (c > 0) {
157 | window.requestAnimationFrame(scrollToTop);
158 | window.scrollTo(0, c - c / 8);
159 | }
160 | };
161 | // el是否在视口范围内
162 | export const elementIsVisibleInViewport = (el, partiallyVisible = false) => {
163 | const { top, left, bottom, right } = el.getBoundingClientRect();
164 | const { innerHeight, innerWidth } = window;
165 | return partiallyVisible
166 | ? ((top > 0 && top < innerHeight) ||
167 | (bottom > 0 && bottom < innerHeight)) &&
168 | ((left > 0 && left < innerWidth) || (right > 0 && right < innerWidth))
169 | : top >= 0 && left >= 0 && bottom <= innerHeight && right <= innerWidth;
170 | };
171 | // 洗牌算法随机
172 | export const shuffle = (arr) => {
173 | var result = [],
174 | random;
175 | while (arr.length > 0) {
176 | random = Math.floor(Math.random() * arr.length);
177 | result.push(arr[random]);
178 | arr.splice(random, 1);
179 | }
180 | return result;
181 | };
182 | // 劫持粘贴板
183 | export const copyTextToClipboard = (value) => {
184 | var textArea = document.createElement("textarea");
185 | textArea.style.background = "transparent";
186 | textArea.value = value;
187 | document.body.appendChild(textArea);
188 | textArea.select();
189 | try {
190 | var successful = document.execCommand("copy");
191 | } catch (err) {
192 | console.log("Oops, unable to copy");
193 | }
194 | document.body.removeChild(textArea);
195 | };
196 | // 阻止默认事件
197 | export const stopDefault = (e) => {
198 | //阻止默认浏览器动作(W3C)
199 | if (e && e.preventDefault) {
200 | //火狐的 事件是传进来的e
201 | e.preventDefault();
202 | }
203 | //IE中阻止函数器默认动作的方式
204 | else {
205 | //ie 用的是默认的event
206 | event.returnValue = false;
207 | }
208 | }
209 | // 其他参考 http://static.699pic.com/js/utils.v1.js
210 | /**
211 | * 将 new Date() 或者时间戳(秒或者 毫秒都可以) 格式化
212 | *
213 | * @param {*} time new Date() 或者 1590131660 或者 1548221490638
214 | * @param {*} cFormat 形如 '{y}年{m}月{d}日 {h}:{i} 周{a}'
215 | * @returns @String
216 | */
217 | export const parseTimeFn = (time, cFormat) => {
218 | if (arguments.length === 0 || !time) {
219 | return null
220 | }
221 | var format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
222 | var date = ''
223 | if (typeof time === 'object') {
224 | date = time
225 | } else {
226 | if ((typeof time === 'string')) {
227 | if (time.length === 10) { time = time * 1000 }
228 | if ((/^[0-9]+$/.test(time))) {
229 | time = parseInt(time)
230 | } else {
231 | time = time.replace(new RegExp(/-/gm), '/')
232 | }
233 | }
234 | if ((typeof time === 'number') && (time.toString().length === 10)) {
235 | time = time * 1000
236 | }
237 | date = new Date(time)
238 | }
239 | var formatObj = {
240 | y: date.getFullYear(),
241 | m: date.getMonth() + 1,
242 | d: date.getDate(),
243 | h: date.getHours(),
244 | i: date.getMinutes(),
245 | s: date.getSeconds(),
246 | a: date.getDay()
247 | }
248 | var time_str = format.replace(/{([ymdhisa])+}/g, function (result, key) {
249 | var value = formatObj[key]
250 | if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value] }
251 | return paddingLeftZero(value.toString())
252 | })
253 | return time_str
254 | }
255 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## 基于小业务的一些基础功能性代码
2 |
3 |
4 |
5 | #### (一)、网页中 点击复制到剪贴板 功能 实现
6 |
7 | 1. IE有一个 `window.clipboardData`接口设置复制内容,考虑兼容性即可
8 | 2. 最早尝试的是 使用execCommand;
9 |
10 | ```javascript
11 | function jsCopy(){
12 | var e=document.getElementById("target-dom");//获取目标dom
13 | e.select(); //选择对象
14 | document.execCommand("Copy"); //执行浏览器复制命令
15 | alert("复制成功");
16 | }
17 | ```
18 |
19 | 在 Chrome 60版本并没有生效,直接pass掉
20 |
21 | 1. clipboard.min.js
22 |
23 | 与其在原生js 一棵树上吊死,不如考虑 jQuery(老夫上去就是一把jQuery)的一些插件啊
24 |
25 | 对着 文档一顿操作,初始化插件,需要的地方 布置 __data-clipboard-action="copy" data-clipboard-target__ 然而在我调试的时间内 ,我并未完成 点击复制多个内容 遂放弃 兼容性并未测试,不过 根据官方提供的是Chrome 42+、Firefox 41+、IE 9+、Opera 29+ 并不满足我的需求
26 |
27 | 2. 继续 尝试新的姿势
28 |
29 | 博客园等给我的推荐 zeroClipboard 这款插件,看到 flash 止步。毕竟flash这货儿 我不熟,而且逐渐被主流浏览器遗弃,为他默哀一秒,好 时间到
30 |
31 | 3. How to resolve this FXXking question
32 |
33 | 模拟一个看不见的textarea,获取里面预设的内容信息。show you the code
34 |
35 | ```javascript
36 | function copyTextToClipboard(value) {
37 | var textArea = document.createElement("textarea");
38 | textArea.style.background = 'transparent';//尽量不让用户感知
39 | textArea.value = value;
40 | document.body.appendChild(textArea);
41 | textArea.select();
42 | try {
43 | var successful = document.execCommand('copy');
44 | var msg = successful ? 'successful' : 'unsuccessful';
45 | console.log(msg);//
46 | } catch (err) {
47 | console.log('Oops, unable to copy');
48 | }
49 | document.body.removeChild(textArea);//去除textarea 容器
50 | }
51 | ```
52 |
53 | 完美解决我的需求
54 |
55 | #### (二)、 读写localStorage
56 |
57 | ```javascript
58 | function writeClientStorage(key,val){
59 | localStorage.setItem(key, JSON.stringify(val));
60 | }
61 | function readClientStorage(key){
62 | var readValue = localStorage.getItem(key);
63 | if(readValue=='undefined' || readValue == null){
64 | return null;
65 | }else{
66 | return JSON.parse(readValue);
67 | }
68 | }
69 | ```
70 |
71 |
72 |
73 | #### (三)、 关于随机数
74 |
75 | ```javascript
76 | //获取不同的随机数
77 | function getRandomArrayElements(arr, count) {
78 | var shuffled = arr.slice(0),
79 | i = arr.length,
80 | min = i - count,
81 | temp, index;
82 | while (i-- > min) {
83 | index = Math.floor((i + 1) * Math.random());
84 | temp = shuffled[index];
85 | shuffled[index] = shuffled[i];
86 | shuffled[i] = temp;
87 | }
88 | return shuffled.slice(min);
89 | }
90 |
91 | // 拟定sort排序规则
92 | function sequence(a, b) {
93 | if (a > b) {
94 | return 1;
95 | } else if (a < b) {
96 | return -1
97 | } else {
98 | return 0;
99 | }
100 | }
101 | //
102 | ```
103 |
104 | #### (四)、 移动端比较好用的 reset.css
105 |
106 | 亮点在于 设计稿除以40px 等于 对应的 rem 布局,实际表现良好
107 |
108 | ```css
109 | body,html{height:100%; user-select:none;}
110 | html{font-size: 100% !important;}
111 | body{-webkit-overflow-scrolling: touch;background:#fafafa;}
112 | *{margin:0; padding:0;-webkit-tap-highlight-color:rgba(0,0,0,0);
113 | body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form, fieldset,input,textarea,p,blockquote,th,td{margin:0; padding:0; }
114 | body, div, ul, li, h1, h2, h3, h4, h5, h6, input, button, p, a, i {margin:0; padding:0; font-family:PingFang-SC-Regular,sans-serif; font-weight:normal; font-style:normal;}
115 | ul,li {list-style:none }
116 | h1,h2,h3,h4,h5,h6{font-weight:normal;}
117 | table{border-collapse:collapse }
118 | img{width:100%; height:auto; display:block; overflow:hidden; border:0; }
119 | select, input{vertical-align:middle; _vertical-align:baseline; outline:none;}
120 | a{text-decoration:none; outline:0; cursor:pointer; outline:none;}
121 | a:active{text-decoration:none;opacity: 0.5;}
122 | a:visited{text-decoration:none;opacity: 0.5;}
123 | input[type="reset"]::-moz-focus-inner,
124 | input[type="button"]::-moz-focus-inner,
125 | input[type="submit"]::-moz-focus-inner,
126 | input[type="file"]>input[type="button"]::-moz-focus-inner {border:0 none ;padding:0; appearance:none; -moz-appearance:none; -webkit-appearance:none;}
127 | input[type="button"], input[type="submit"], input[type="reset"] {-webkit-appearance:none;}
128 | textarea{-webkit-appearance:none;resize:none; outline:none;}
129 | @media only screen and (min-width: 351px) {
130 | html {font-size:125%!important/*换算比例:设计稿尺寸除以40所得尺寸即为页面实际尺寸*/}
131 | }
132 | .clear{clear:both; font-size:0; height:0; overflow:hidden }
133 | .clearfix{zoom:1 }
134 | .clearfix:after{content:"."; display:block; height:0; clear:both; visibility:hidden }
135 | ::-webkit-scrollbar{width:0px;height: 0px;}/*滚动条*/
136 | :-moz-placeholder { /* Mozilla Firefox 4 to 18 */ color:rgba(255,255,255,1);}
137 | ::-moz-placeholder { /* Mozilla Firefox 19+ */ color:rgba(255,255,255,1);}
138 | input:-ms-input-placeholder,
139 | textarea:-ms-input-placeholder{color:rgba(255,255,255,1)}
140 | input::-webkit-input-placeholder,
141 | textarea::-webkit-input-placeholder{color:rgba(255,255,255,1);}
142 | ```
143 |
144 |
145 |
146 | #### (五)、 多组数据随机取几组数据
147 |
148 | ```javascript
149 | /*
150 | * 传入 数组,传入 最终需要 随机的 长度,返回 新的 数组
151 | * like 6组数据 需要 随机 2组数据
152 | * @arr: 被处理数组
153 | * @res_len:最终返回 的 随机新数组的长度
154 | */
155 | function get_random_res_arr_with_length(arr,res_len) {
156 | var res_arr = [];
157 | var length = arr.length;
158 | var arr_with_num = new Array(length);
159 | for(var i = 0; i0) {
178 | var arrIndex = Math.floor(Math.random()*temp_array.length);
179 | return_array[i] = temp_array[arrIndex];
180 | temp_array.splice(arrIndex, 1);
181 | } else {
182 | break;
183 | }
184 | }
185 | return return_array;
186 | }
187 | ```
188 |
189 |
190 |
191 | #### (六)、 时间比较(time Differ)
192 |
193 | ```javascript
194 | // 处理/比较 时间戳
195 | function get_timestamp_diff(timestamps){
196 | var result = '';
197 |
198 | var minute = 60;
199 | var hour = minute * 60;
200 | var day = hour * 24;
201 | var month = day * 30;
202 |
203 | var now = (new Date()).getTime()/1000;
204 | var distance = now-timestamps;
205 | if(distance<0){return;}
206 | var monthC = distance/month;
207 | var weekC = distance/(7*day);
208 | var dayC = distance/day;
209 | var hourC = distance/hour;
210 | var minC = distance/minute;
211 | if(monthC>=1){
212 | if(parseInt(monthC) / 12>=1) {
213 | result = parseInt(parseInt(monthC) / 12)+'年前';
214 | } else {
215 | result = parseInt(monthC)+'月前';
216 | }
217 | }else if(weekC>=1){
218 | result = parseInt(weekC)+'周前';
219 | }else if(dayC>=1){
220 | result = parseInt(dayC)+'天前';
221 | }else if(hourC>=1){
222 | result = parseInt(hourC)+'小时前';
223 | }else if(minC>=1){
224 | result = parseInt(minC)+'分钟前';
225 | }else{
226 | result = '刚刚';
227 | }
228 | return result
229 | }
230 | ```
231 |
232 |
233 |
234 | #### (七)、 洗牌算法,随机排序 非常好用
235 |
236 | ```javascript
237 | // 洗牌算法 -- MadeBy SunPing
238 | function shuffle(arr){
239 | var result = [],
240 | random;
241 | while(arr.length>0){
242 | random = Math.floor(Math.random() * arr.length);
243 | result.push(arr[random])
244 | arr.splice(random, 1)
245 | }
246 | return result;
247 | }
248 | ```
249 |
250 |
251 |
252 | #### (八)、 Bae64
253 |
254 | ```javascript
255 | var Base64 = {
256 | _keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
257 | encode: function(e) {
258 | var t = "";
259 | var n, r, i, s, o, u, a;
260 | var f = 0;
261 | e = Base64._utf8_encode(e);
262 | while (f < e.length) {
263 | n = e.charCodeAt(f++);
264 | r = e.charCodeAt(f++);
265 | i = e.charCodeAt(f++);
266 | s = n >> 2;
267 | o = (n & 3) << 4 | r >> 4;
268 | u = (r & 15) << 2 | i >> 6;
269 | a = i & 63;
270 | if (isNaN(r)) { u = a = 64 } else if (isNaN(i)) { a = 64 } t = t + this._keyStr.charAt(s) + this._keyStr.charAt(o) + this._keyStr.charAt(u) + this._keyStr.charAt(a)
271 | }
272 | return t
273 | },
274 | decode: function(e) {
275 | var t = "";
276 | var n, r, i;
277 | var s, o, u, a;
278 | var f = 0;
279 | e = e.replace(/[^A-Za-z0-9+/=]/g, "");
280 | while (f < e.length) {
281 | s = this._keyStr.indexOf(e.charAt(f++));
282 | o = this._keyStr.indexOf(e.charAt(f++));
283 | u = this._keyStr.indexOf(e.charAt(f++));
284 | a = this._keyStr.indexOf(e.charAt(f++));
285 | n = s << 2 | o >> 4;
286 | r = (o & 15) << 4 | u >> 2;
287 | i = (u & 3) << 6 | a;
288 | t = t + String.fromCharCode(n);
289 | if (u != 64) { t = t + String.fromCharCode(r) }
290 | if (a != 64) { t = t + String.fromCharCode(i) }
291 | }
292 | t = Base64._utf8_decode(t);
293 | return t
294 | },
295 | _utf8_encode: function(e) {
296 | e = e.replace(/rn/g, "n");
297 | var t = "";
298 | for (var n = 0; n < e.length; n++) {
299 | var r = e.charCodeAt(n);
300 | if (r < 128) { t += String.fromCharCode(r) } else if (r > 127 && r < 2048) {
301 | t += String.fromCharCode(r >> 6 | 192);
302 | t += String.fromCharCode(r & 63 | 128)
303 | } else {
304 | t += String.fromCharCode(r >> 12 | 224);
305 | t += String.fromCharCode(r >> 6 & 63 | 128);
306 | t += String.fromCharCode(r & 63 | 128)
307 | }
308 | }
309 | return t
310 | },
311 | _utf8_decode: function(e) {
312 | var t = "";
313 | var n = 0;
314 | var r = c1 = c2 = 0;
315 | while (n < e.length) {
316 | r = e.charCodeAt(n);
317 | if (r < 128) {
318 | t += String.fromCharCode(r);
319 | n++
320 | } else if (r > 191 && r < 224) {
321 | c2 = e.charCodeAt(n + 1);
322 | t += String.fromCharCode((r & 31) << 6 | c2 & 63);
323 | n += 2
324 | } else {
325 | c2 = e.charCodeAt(n + 1);
326 | c3 = e.charCodeAt(n + 2);
327 | t += String.fromCharCode((r & 15) << 12 | (c2 & 63) << 6 | c3 & 63);
328 | n += 3
329 | }
330 | }
331 | return t
332 | }
333 | }
334 | ```
335 |
336 | #### (九)cookie
337 | __此处的cookie操作不够严谨,建议参考 [issues](https://github.com/CracKerMe/dev_code/issues/1)__
338 |
339 | ```javascript
340 | var GetCookie = {
341 | get: function(name) {
342 | var arr, reg = new RegExp("(^| )" + name + "=([^;]*)(;|$)");
343 | if (arr = document.cookie.match(reg)) return unescape(arr[2]);
344 | else return '';
345 | }
346 | }
347 |
348 | var SetCookie = {
349 | set: function(name, value) {
350 | var Days = 30;
351 | var exp = new Date();
352 | exp.setTime(exp.getTime() + Days * 24 * 60 * 60 * 1000);
353 | document.cookie = name + "=" + escape(value) + ";expires=" + exp.toGMTString();
354 | }
355 | }
356 | ```
357 |
358 |
359 |
360 | #### (十)对象合并的 Polyfill 写法(Object.assign)
361 |
362 |
363 | ```javascript
364 | if (!Object.assign) {
365 | Object.defineProperty(Object, "assign", {
366 | enumerable: false,
367 | configurable: true,
368 | writable: true,
369 | value: function(target, firstSource) {
370 | "use strict";
371 | if (target === undefined || target === null)
372 | throw new TypeError("Cannot convert first argument to object");
373 | var to = Object(target);
374 | for (var i = 1; i < arguments.length; i++) {
375 | var nextSource = arguments[i];
376 | if (nextSource === undefined || nextSource === null) continue;
377 | var keysArray = Object.keys(Object(nextSource));
378 | for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++) {
379 | var nextKey = keysArray[nextIndex];
380 | var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
381 | if (desc !== undefined && desc.enumerable) to[nextKey] = nextSource[nextKey];
382 | }
383 | }
384 | return to;
385 | }
386 | });
387 | ```
388 |
389 | #### (十一)获取` yy-MM-dd hh:mm:ss` 的标准时间格式
390 | - 小程序版本 获取` yy-MM-dd hh:mm:ss` 的标准时间格式
391 |
392 | ```
393 | const formatTime = date => {
394 | const year = date.getFullYear()
395 | const month = date.getMonth() + 1
396 | const day = date.getDate()
397 | const hour = date.getHours()
398 | const minute = date.getMinutes()
399 | const second = date.getSeconds()
400 |
401 | return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':')
402 | }
403 |
404 | const formatNumber = n => {
405 | n = n.toString()
406 | return n[1] ? n : '0' + n
407 | }
408 |
409 | module.exports = {
410 | formatTime: formatTime
411 | }
412 |
413 | ```
414 |
415 | - 原生js 获取` yy-MM-dd hh:mm:ss` 的标准时间格式
416 |
417 |
418 | ```
419 | Date.prototype.Format = function (fmt) {
420 | var o = {
421 | "M+": this.getMonth() + 1, //月份
422 | "d+": this.getDate(), //日
423 | "h+": this.getHours(), //小时
424 | "m+": this.getMinutes(), //分
425 | "s+": this.getSeconds(), //秒
426 | "q+": Math.floor((this.getMonth() + 3) / 3), //季度
427 | "S": this.getMilliseconds() //毫秒
428 | }
429 | if (/(y+)/.test(fmt)) {
430 | fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length))
431 | }
432 | for (var k in o) {
433 | if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)))
434 | }
435 | return fmt
436 | }
437 | ```
438 |
439 | - 做了一层封装
440 | ```
441 | // format: 0 => 2019-04-29
442 | // 1 => 2019-04-29 17:09
443 | // 2 => 2019-04-29 17:09:37
444 | function monment(timestamp, format, divide) {
445 | var tempDate = new Date(),
446 | result = '',
447 | divide = divide || '-';
448 | if(!timestamp) {
449 | timestamp = new Date().getTime();
450 | }
451 | tempDate.setTime(timestamp);
452 | var year = tempDate.getFullYear()
453 | var month = paddingLeftZero(tempDate.getMonth() + 1)
454 | var day = paddingLeftZero(tempDate.getDate())
455 | var hour = paddingLeftZero(tempDate.getHours())
456 | var minute = paddingLeftZero(tempDate.getMinutes())
457 | var second = paddingLeftZero(tempDate.getSeconds())
458 | switch (format) {
459 | case 0:
460 | result = year+divide+month+divide+day;
461 | break;
462 | case 1:
463 | result = year+divide+month+divide+day+' '+hour+':'+minute;
464 | break;
465 | case 2:
466 | result = year+divide+month+divide+day+' '+hour+':'+minute+':'+second;
467 | break;
468 | }
469 | return result
470 | }
471 | ```
472 |
473 | #### (十二)获取url参数实例
474 | ```
475 | > url参数符合规范要求(like ?a=1&b=2&c=3)
476 | function getQueryString(name) {
477 | const reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i');
478 | const search = window.location.search.split('?')[1] || '';
479 | const r = search.match(reg) || [];
480 | return r[2];
481 | }
482 | > url参数不符合规范要求(like ?a=1&b=2?c=3)
483 | function GetParams(temp, name) {
484 | var theRequest = new Object();
485 | var strs = temp.split("&");
486 | for (var i = 0; i < strs.length; i++) {
487 | theRequest[strs[i].split("=")[0]] = (strs[i].split("=")[1]);
488 | }
489 | // 获取 参数对象的指定key 的 value值
490 | var result = theRequest[name] || null;
491 | return result;
492 | }
493 | function getQueryString(name) {
494 | // 获取当前 URL参数集
495 | var r = decodeURI(window.location.search);
496 | var arr1 = r.split("?");
497 | arr1.shift();
498 | var params = arr1.join("&");
499 | var res = GetParams(params, name);
500 | return res;
501 | }
502 | ```
503 |
504 | #### (十三)下载图片文件 base64
505 | ```
506 | function downloadFile(fileName, content) {
507 |
508 | var aLink = document.createElement('a');
509 |
510 | var blob = base64Img2Blob(content);
511 |
512 | var evt = document.createEvent("MouseEvents");
513 |
514 | evt.initEvent("click", false, false);//initEvent 不加后两个参数在FF下会报错
515 |
516 | aLink.download = fileName;
517 |
518 | aLink.href = URL.createObjectURL(blob);
519 |
520 | aLink.dispatchEvent(evt);
521 |
522 | }
523 |
524 | ```
525 |
526 | #### (十四)掘金式复制拦截
527 | ```javascript
528 | document.body.oncopy = event => {
529 | event.preventDefault(); // 取消默认的复制事件
530 | let textFont, copyFont = window.getSelection(0).toString(); // 被复制的文字 等下插入
531 | // 超过一定长度的文字 就添加版权信息
532 | if (copyFont.length > 10) {
533 | textFont = copyFont + '\n'
534 | + '作者:AppleSun\n'
535 | + '链接:'+ window.location.href +'\n'
536 | + '来源:博客\n'
537 | + '著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。';
538 | } else {
539 | textFont = copyFont; // 没超过十个字 则采用被复制的内容。
540 | }
541 | if (event.clipboardData) {
542 | return event.clipboardData.setData('text', textFont); // 将信息写入粘贴板
543 | } else {
544 | // 兼容IE
545 | return window.clipboardData.setData("text", textFont);
546 | }
547 | }
548 | ```
549 |
550 | #### (十五)无视浏览器拦截 打开新页面跳转
551 | ```
552 | // window.titleName 是为了统一 跳转器命名,并且保持随机关系,如果不随机,将只能打开一个页面
553 | window.titleName = 'search'+(new Date().getTime());
554 | /*openInNewTab实现:增加用户行为触发*/
555 | var openInNewTab = function(url) {
556 | var a = document.createElement("a");
557 | a.setAttribute("href", url);
558 | a.setAttribute("target", window.titleName);
559 | document.body.appendChild(a);
560 | a.click();
561 | }
562 | // 更新已打开窗口的url
563 | function updateNewWindowUrl(url) {
564 | var newWindow = window.open(null, window.titleName);
565 | newWindow.location.href = url;
566 | }
567 |
568 | // 在click等事件中,先触发`openInNewTab('about:blank')`;
569 | // 然后获得正确的 newUrl 地址后 `updateNewWindowUrl(newUrl)`;
570 | ```
571 |
572 | #### (十六)es5 emit
573 | ```
574 | var globalEmit = (function () {
575 | var events = {}
576 | function on(evt, handler) {
577 | events[evt] = events[evt] || []
578 | events[evt].push({
579 | handler: handler
580 | })
581 | }
582 | function trigger(evt, args) {
583 | if(!events[evt]) {
584 | return
585 | }
586 | for (var i = 0; i < events[evt].length; i++) {
587 | events[evt][i].handler(args)
588 | }
589 | }
590 | return {
591 | on: on,
592 | trigger: trigger
593 | }
594 | })();
595 | // listen Event && callback
596 | globalEmit.on('CUSTOM_EVENT', function(){
597 | // your callback here
598 | });
599 | // trigger Event
600 | globalEmit.trigger('CUSTOM_EVENT');
601 | ```
602 |
603 | #### (十七)localStorage with outdate time
604 | 自定义 LocalStorage 处理(有过期时间功能)
605 | ```
606 | function customLocalStorage() {
607 | this.set = function (key,value) {
608 | var curTime = new Date().getTime();
609 | localStorage.setItem(key,JSON.stringify({data:value,time:curTime}));
610 | }
611 | this.get = function (key,exp) {
612 | var data = localStorage.getItem(key);
613 | if (data) {
614 | var dataObj = JSON.parse(data);
615 | if(!exp) {
616 | var dataObjDatatoJson = dataObj.data
617 | return dataObjDatatoJson;
618 | }
619 | if (new Date().getTime() - dataObj.time>exp) {
620 | console.log('信息已过期');
621 | // your callbak here
622 | }else{
623 | var dataObjDatatoJson = dataObj.data
624 | return dataObjDatatoJson;
625 | }
626 | }
627 | },
628 | this.remove = function (key) {
629 | localStorage.removeItem(key);
630 | }
631 | };
632 | ```
633 |
634 | #### (十八)获取浏览器经纬度
635 | ```
636 | function getPosition () {
637 | return new Promise((resolve, reject) => {
638 | if (navigator.geolocation) {
639 | navigator.geolocation.getCurrentPosition(function (position) {
640 | let latitude = position.coords.latitude
641 | let longitude = position.coords.longitude
642 | let data = {
643 | latitude: latitude,
644 | longitude: longitude
645 | }
646 | resolve(data)
647 | }, function () {
648 | reject(arguments)
649 | })
650 | } else {
651 | reject('你的浏览器不支持当前地理位置信息获取')
652 | }
653 | })
654 | }
655 | /* 调用如下 */
656 | getPosition().then(result => {
657 | let queryData = {
658 | longtitude: String(result.longitude).match(/\d+\.\d{0,6}/)[0],
659 | latitude: String(result.latitude).match(/\d+\.\d{0,6}/)[0],
660 | channelType: '00'
661 | }
662 | console.log(queryData)
663 | }).catch(err => {
664 | console.log(err)
665 | })
666 | ```
667 |
668 | #### (十九) 是否是爬虫
669 | ```
670 | function isSprider (str) {
671 | if(/adsbot|googlebot|bingbot|msnbot|yandexbot|baidubot|robot|careerbot|seznambot|bot|baiduspider|jikespider|symantecspider|scanner|webcrawler|crawler|Sogou+web+spider/i.test(str)) {
672 | return true
673 | } else {
674 | return false
675 | }
676 | }
677 | ```
678 |
679 | #### (二十)下载图片
680 | ```
681 | function downloadFile(fileName, url) {
682 | if (isIE()) {
683 | window.open(url)
684 | } else {
685 | var iframe = document.createElement("iframe");
686 | iframe.style.display = "none";
687 | iframe.style.height = 0;
688 | iframe.src = url;
689 | document.body.appendChild(iframe);
690 | setTimeout(function() {
691 | iframe.remove();
692 | }, 5 * 60 * 1000);
693 | }
694 | };
695 | ```
696 |
697 | #### (二十一)是否是微信内核 是否是QQ内核
698 | ```
699 | function isWeixin () { //判断是否是微信
700 | var ua = navigator.userAgent.toLowerCase();
701 | return ua.match(/microMessenger/i) == "micromessenger";
702 | };
703 | function isQQBrowser () { //判断是否是QQ浏览器
704 | var ua = navigator.userAgent.toLowerCase();
705 | /* qbwebviewtype特指ios版的手Q */
706 | return !!ua.match(/mqqbrowser|qzone|qqbrowser|qbwebviewtype/i);
707 | };
708 | ```
709 |
710 | #### (二十二)JS精度丢失
711 | ```
712 | /* e.g: */
713 | 0.1+0.2
714 | /* 结果返回 0.30000000000000004 */
715 |
716 | strip(0.1+0.2)
717 | /* 结果返回 0.3 */
718 | function strip(num, precision = 12) {
719 | return +parseFloat(num.toPrecision(precision));
720 | }
721 | ```
722 |
723 | #### (二十三)hire console.log
724 | ```
725 | console.log("\n _____ _____ _____ _____ \n /\\ \\ /\\ \\ /\\ \\ /\\ \\ \n /::\\____\\ /::\\ \\ /::\\ \\ /::\\ \\ \n /:::/ / \\:::\\ \\ /::::\\ \\ /::::\\ \\ \n /:::/ / \\:::\\ \\ /::::::\\ \\ /::::::\\ \\ \n /:::/ / \\:::\\ \\ /:::/\\:::\\ \\ /:::/\\:::\\ \\ \n /:::/____/ \\:::\\ \\ /:::/__\\:::\\ \\ /:::/__\\:::\\ \\ \n /::::\\ \\ /::::\\ \\ /::::\\ \\:::\\ \\ /::::\\ \\:::\\ \\ \n /::::::\\ \\ _____ ____ /::::::\\ \\ /::::::\\ \\:::\\ \\ /::::::\\ \\:::\\ \\ \n /:::/\\:::\\ \\ /\\ \\ /\\ \\ /:::/\\:::\\ \\ /:::/\\:::\\ \\:::\\____\\ /:::/\\:::\\ \\:::\\ \\ \n/:::/ \\:::\\ /::\\____\\/::\\ \\/:::/ \\:::\\____\\/:::/ \\:::\\ \\:::| |/:::/__\\:::\\ \\:::\\____\\\n\\::/ \\:::\\ /:::/ /\\:::\\ /:::/ \\::/ /\\::/ |::::\\ /:::|____|\\:::\\ \\:::\\ \\::/ /\n \\/____/ \\:::\\/:::/ / \\:::\\/:::/ / \\/____/ \\/____|:::::\\/:::/ / \\:::\\ \\:::\\ \\/____/ \n \\::::::/ / \\::::::/ / |:::::::::/ / \\:::\\ \\:::\\ \\ \n \\::::/ / \\::::/____/ |::|\\::::/ / \\:::\\ \\:::\\____\\ \n /:::/ / \\:::\\ \\ |::| \\::/____/ \\:::\\ \\::/ / \n /:::/ / \\:::\\ \\ |::| ~| \\:::\\ \\/____/ \n /:::/ / \\:::\\ \\ |::| | \\:::\\ \\ \n /:::/ / \\:::\\____\\ \\::| | \\:::\\____\\ \n \\::/ / \\::/ / \\:| | \\::/ / \n \\/____/ \\/____/ \\|___| \\/____/ \n\n知乎(zhihu.com),招聘前端开发工程师 http://zhi.hu/BDXoD\n ")
726 | ```
727 | 以及有趣的console.log
728 | ```
729 | console.log("%c %c您的选择, %c我们的荣耀", "background:url(http://moyu.awebman.com/public/logo.png) no-repeat left center;font-size: 16px;line-height:60px; overflow: hidden", "fonst-size: 14px;color: #000000", "fonst-size: 14px;color: #000000");
730 |
731 | /* 还有我的博客正在使用的 */
732 | console.log('\n %c 已找到工作了,针对博客有啥想交流的,联系QQ: 1160948478 \n', 'color:#455a64;background:#e0e0e0;padding:5px 0;border-radius:5px;');
733 | ```
734 |
735 | ```
736 | /* 当天0点0分0秒 */
737 | new Date(new Date(new Date().toLocaleDateString()).getTime());
738 | /* 当天23点59分59秒 */
739 | new Date(new Date(new Date().toLocaleDateString()).getTime()+24*60*60*1000-1);
740 | ```
741 |
742 | #### (二十四) 手写骨架屏css
743 | ```
744 |
745 |
746 | .skeleton-text {background: linear-gradient(90deg,#f2f2f2 25%,#e6e6e6 37%,#f2f2f2 63%);background-size: 400% 100%;animation: skeleton-loading 1.4s ease infinite;height: 22px;}
747 | @keyframes skeleton-loading {
748 | 0% {background-position: 100% 50%;}
749 | 100% {background-position: 0 50%;}
750 | }
751 | ```
752 |
753 | __Yours Sincerely AppleSun__
754 |
--------------------------------------------------------------------------------