├── README.md ├── app.js ├── utils.js ├── 滚动条.md └── 禁止调试js /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /滚动条.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 | -------------------------------------------------------------------------------- /禁止调试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 | --------------------------------------------------------------------------------