🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
## 一、字母数字排序 ~~~ function mySorter(a, b){ if (/^\d/.test(a) ^ /^\D/.test(b)) return a>b?1:(a==b?0:-1); // ^ 异或(不同为1,相同为0) return a>b?-1:(a==b?0:1); } var pyArray = ["a","d","fa","5","t","fw2","a31","b","e","2fs","4","0"]; console.log(pyArray.sort(mySorter)) ~~~ ## 二、jquery的观察者模式 使用场景:如果页面有多个setInterval的时候,可以使用观察者模式,当然还有其他,具体根据项目来 ~~~ (function ($) { var o = $({}); $.subscribe = function () { o.on.apply(o, arguments); }; $.unsubscribe = function () { o.off.apply(o, arguments); }; $.publish = function () { o.trigger.apply(o, arguments); }; }(jQuery)); var startTime = 0; setInterval(function() { startTime++; if(startTime%3 === 0) { $.publish("a", ["a", "b", "c"]); // 输出abc } if(startTime%2 === 0) { $.publish("b", ['bb']); // 输出abc } }, 1000); $.subscribe("a", function(e, a, b, c) { console.log(e); console.log(a, b, c); }); $.subscribe("b", function(e, arg1) { console.log(arg1) }); /* //回调函数 function handle(e, a, b, c) { // `e`是事件对象,不需要关注 console.log(a + b + c); }; //订阅 $.subscribe("/some/topic", handle); //发布 $.publish("/some/topic", ["a", "b", "c"]); // 输出abc $.unsubscribe("/some/topic", handle); // 退订 //订阅 $.subscribe("/some/topic", function (e, a, b, c) { console.log(a + b + c); }); $.publish("/some/topic", ["a", "b", "c"]); // 输出abc //退订(退订使用的是/some/topic名称,而不是回调函数哦,和版本一的例子不一样 $.unsubscribe("/some/topic"); */ ~~~ ## 三、div 高度100% ~~~ html,body{height: 100%}; div{height: 100%;} ~~~ ## 四、手动拼装JSON字符串需要加双引号 ~~~ '{"name": "tom", "age": 24}' ~~~ ## 五、解板字符串boolean值 ~~~ var flag = 'true'; console.log(eval(flag)); // true; eval会造成性能损耗,不建议使用 console.log(JSON.parse(flag)); // true,可以尝试 ~~~ ## 六、json变量键名 ~~~ // 方式1 var params = {}; var fnum = 'MU1234', anum = 'B1234'; params[fnum] = anum; // 方式2 {[fnum]: anum} // 方式3 请参考es6语法 ~~~ ## 七、在JSON中,前导零是禁止的(在 JSON. 零将被忽略,但在 JSON.parse 它将抛出 SyntaxError);小数点后必须至少有一位数字。还有前导为0的时候输出的顺序也会发生变化。 ~~~ var foo = { "00": "a", "01": "b", "02": "c", "10": "d", "11": "e", "12": "f" }; for(var i in foo) { console.log(foo[i]); // d e f a b c } ~~~ 排序解决方案:可在键名前加个字符 ## 八、巧用bind ~~~ var $ = document.querySelector.bind(document); $('.box').textContent = 'hello world ~'; ~~~ ## 九、两个字母比较可以先转为unicode码 ~~~ console.log('B'.charCodeAt(0) < 'C'.charCodeAt(0)); // true ~~~ ## 十、获取数据类型 ~~~ function getType(data) { return Object.prototype.toString.call(data).replace(/^\[object (.+)\]$/, '$1').toLowerCase(); } console.log(getType(true)); // boolean console.log(getType(1)); // number ~~~ ## 十一、淡入淡出效果 ~~~ function fadeIn(el) { var opacity = 0; el.style.opacity = 0; el.style.filter = ''; var last = +new Date(); var tick = function() { opacity += (new Date() - last) / 400; el.style.opacity = opacity; el.style.filter = 'alpha(opacity=' + (100 * opacity)|0 + ')'; last = +new Date(); if (opacity < 1) { (window.requestAnimationFrame && requestAnimationFrame(tick)) || setTimeout(tick, 16); } }; tick(); } fadeIn(el); ~~~ ## 十二、添加className ~~~ if (el.classList) el.classList.add(className); else el.className += ' ' + className; ~~~ ## 十三、在元素之前添加html(之后是afterend) ~~~ el.insertAdjacentHTML('beforebegin', htmlString); ~~~ ## 十四、遍历元素 ~~~ function forEachElement(selector, fn) { var elements = document.querySelectorAll(selector); for (var i = 0; i < elements.length; i++) fn(elements[i], i); } forEachElement(selector, function(el, i){ }); ~~~ ## 十五、判断是否有class ~~~ if (el.classList) el.classList.contains(className); else new RegExp('(^| )' + className + '( |$)', 'gi').test(el.className); ~~~ ## 十六、判断元素是否是指定元素 ~~~ var matches = function(el, selector) { var _matches = (el.matches || el.matchesSelector || el.msMatchesSelector || el.mozMatchesSelector || el.webkitMatchesSelector || el.oMatchesSelector); if (_matches) { return _matches.call(el, selector); } else { var nodes = el.parentNode.querySelectorAll(selector); for (var i = nodes.length; i--;) { if (nodes[i] === el) return true; } return false; } }; matches(el, '.my-class'); ~~~ ## 十七、获取outer宽度(高度同理) ~~~ function outerWidth(el) { var width = el.offsetWidth; var style = el.currentStyle || getComputedStyle(el); width += parseInt(style.marginLeft) + parseInt(style.marginRight); return width; } outerWidth(el); ~~~ ## 十八、删除class ~~~ if (el.classList) el.classList.remove(className); else el.className = el.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' '); ~~~ ## 十九、类型转换优先级 ~~~ // 转数字 var status = '1'; // (+status) > Number(status) > Math.round(status) > parseInt(status) // 转字符串 var status = 1; // (''+status) > String(status) > status.toString() > new String(status) ~~~ ## 二十、避免引用类型引起的问题 ~~~ // 数组 var arr1 = [1,2,3], arr2 = arr1.concat([]), arr3 = JSON.parse(JSON.stringify(arr1)); // json对象 var json1 = {name: 'tom', age: 24}, json2 = Object.assign({}, json1), json3 = $.extend({}, json1), // jquery方式 json4 = JSON.parse(JSON.stringify(json1)); ~~~ ## 二一、位操作符技巧 ~~~ // 判断奇偶 var a = 3; if(!(a&1)) { // 偶数 } else { // 奇数 } // 舍去小数位 ~~~1.567 // 1 ~~~-1.88 // -1 // 配合indexOf返回boolean值 var str = 'hello'; console.log(!!~str.indexOf('j')); // false ~~~ ## 二二、如果已知返回类型,判断的时候尽量使用===代替==,因为减少了一次js隐式类型转换的操作 ~~~ var num = 1; if(num === 1) { } ~~~ ## 二三、其他类型转换为boolean值 ~~~ !!"" // false !!0 // false !!null // false !!undefined // false !!NaN // false !!"hello" // true !!1 // true !!{} // true !![] // true ~~~ ## 二四、规则类型判断返回,可以使用数组代替switch ~~~ var type = 1; var typeArr = ['开始', '进行中', '打断', '重新开始', '结束']; console.log(typeArr[type]) ~~~ ## 二五、有时候可以使用字符串代替数组,如星期日 到 星期六 ~~~ var oDate = new Date(), day = oDate.getDay(), weekStr = '日一二三四五六'; console.log('星期'+weekStr.charAt(day)); ~~~ ## 二六、不使用jQuery给动态追加的元素添加事件 ``` // jQuery使用on监听 $('body').on('click', '.el-icon-close', function(e) { // ... }); // js使用事件委托 document.addEventListener('click', function(e) { if(e.target.className === 'el-icon-close') { // ...   } }); ```