记录一些平时项目中用到的代码
ES7相关
Async/Await
// http://cnodejs.org/topic/5640b80d3a6aa72c5e0030b6
var sleep = function (time) {
return new Promise(function (resolve, reject) {
setTimeout(function () {
// 返回 ‘ok’
resolve('ok');
}, time);
})
};
var start = async function () {
let result = await sleep(3000);
console.log(result); // 收到 ‘ok’
};
await可以把asnyc当成一个同步函数处理,await等待的虽然是promise对象,但不必写.then(..),直接可以得到返回值。
基本规则
1.async 表示这是一个async函数,await只能用在这个函数里面。
2.await 表示在这里等待promise返回结果了,再继续执行。
3.await 后面跟着的应该是一个promise对象
ES6相关
参数拼接
`这里就是参数${singer.id}前面就是参数` // ES5: '这里就是参数'+singer.id+'前面就是参数'
push, concat
hot.push(...ret) // push写法
[...hot, ...ret] // 数组合并写法: 扩展运算符是三个点“...”,ES5写法 hot.concat(ret)
数组去重
// ES6
// 1: "SET"
let arr = [1,2,3,3,'1','1',NaN,NaN]
function dedupe (array) {
return Array.from(new Set(array))
}
dedupe(arr) // [1, 2, 3, "1", NaN]
// 正常情况下,NaN === NaN 返回的是false,但是在set里,一样能够帮你去重
// 2: "filter"
arr.filter((item, index) => arr.indexOf(item) === index)
// 3: "reduce"
arr.reduce((unique, item) => unique.includes(item) ? unique : [...unique, item], []);
// ES5
var arr=[0,2,3,5,6,9,2];
function dedupeEs5 (array) {
var new_arr=[];
for(var i = 0; i < array.length; i++) {
var items = array[i];
//判断元素是否存在于new_arr中,如果不存在则插入到new_arr的最后
if(new_arr.indexOf(items) === -1) {
new_arr.push(items);
}
}
return new_arr;
}
dedupeEs5(arr); //[0,2,3,5,6,9]
function unique(array) {
var result = [], seen;
array.sort();
for(var i = 0; i < array.length; i++) {
var value = array[i];
if (!seen || seen !== value) {
// 第一次!seen为true,之后都为false
result.push(value);
}
seen = value;
}
return result;
}
// 速度最快, 占空间最多(空间换时间)
// 新建一js对象以及新数组,遍历传入数组时,判断值是否为js对象的键,不是的话给对象新增该键并放入新数组。注意 点: 判断是否为js对象键时,会自动对传入的键执行“toString()”,不同的键可能会被误认为一样;例如: a[1]、a["1"] 。解决上述问题还是得调用“indexOf”。
function unique2(array){
var n = {}, r = [], len = array.length, val, type;
for (var i = 0; i < array.length; i++) {
val = array[i];
type = typeof val;
if (!n[val]) {
n[val] = [type];
r.push(val);
} else if (n[val].indexOf(type) < 0) {
n[val].push(type);
r.push(val);
}
}
return r;
}
一些常用方法
/**
* 实现一个批量请求函数
* 每当有一个请求返回,就留下一个空位,可以增加新的请求
* 所有请求完成后,结果按照数组funcArray里面的顺序依次打出
* @param {Promise[]} funcArray
* @param {number} [limit=5] 要求最大并发数 limit
* @returns Promise<any>
*/
function multiRequest(funcArray: Array<any>, limit: number = 5) {
let i = 0;
let result = []; // 完成集合
let executing = []; // 执行集合
const queue = () => {
if (i === funcArray.length) { // 判断是否全部执行完
return Promise.all(executing);
}
const p = funcArray[i++]();
result.push(p);
const e = p.then(() => executing.splice(executing.indexOf(e), 1)); // 执行完从executing中剔除一个
executing.push(e);
if (executing.length >= limit) { // 判断executing中的长度是否大于等于限制数limit
// 当 Promise.race 时会等到其中一个执行完才执行下一步
return Promise.race(executing).then(() => queue(), e => Promise.reject(e));
}
return Promise.resolve().then(() => queue());
};
return queue().then(() => Promise.all(result)); // 全部执行完按顺序返回
}
/**
* 按序请求接口
* @param {Promise[]} arr
* @param {Callback} 全部请求完成后回调
*/
function asyncs(arr: any[], cb: Callback) {
arr.reduce((p, func) => p.then(func), Promise.resolve()).then(cb);
};
/**
* 树结构查找
* 遍历到满足条件的节点则返回,遍历完成未找到则返回null。类似数组的find方法,传入一个函数用于判断节点是否符合条件
* @param {any[]} tree
* @param {Function} func
* @returns {TreeNode} 树节点
*/
function treeFind(tree: any[], func: any): any | null {
for (let i = 0; i < tree.length; i++) {
let data = tree[i];
if (func(data)) return data;
if (data.children) {
const res = treeFind(data.children, func);
if (res) return res;
}
}
return null;
}
/**
* 先序遍历树结构
* @export
* @param {any[]} tree
* @param {Function} func
*/
function treeForeach(tree: any[], func: Function): void {
tree.forEach(data => {
func(data);
data.children && treeForeach(data.children, func); // 遍历子树
});
}
/**
* 树筛选
* @export
* @param {any[]} tree
* @param {Function} func
*/
function treeFilter(tree: any[], func: Function) {
// 使用map复制一下节点,避免修改到原树
return tree.map(node => ({ ...node })).filter(node => {
node.children = node.children && treeFilter(node.children, func);
return func(node) || (node.children && node.children.length);
});
};
/**
* 判断对象是否为空对象
* [] {} false 0 "" null undefined
*/
function isEmpty(val: any): boolean {
if (val && typeof val === 'object') {
if (val.length && val.length > 0) {
return false;
}
for (let key in val) {
if (window.hasOwnProperty.call(val, key)) {
return false;
}
}
return true;
}
return !val;
}
// 判断是否是移动端简单方法
let inTouch = "ontouchstart" in window.document;
// 不用临时变量交换2个值
function swap(a, b) {
b = b - a;
a = a + b;
b = a - b;
return [a, b];
}
// 交换数组内2个下标的值
arr.splice(x - 1, 1, …arr.splice(y - 1, 1, arr[x - 1]))
// 取范围内随机数
function getRandomInt (min, max) {
return Math.floor(Math.random() * (max - min + 1) + min)
}
// 洗牌(乱序)
function shuffle (arr) {
let _arr = arr.slice()
for (let i = 0; i < _arr.length; i++) {
let j = getRandomInt(0, i)
[arr[i], arr[j]] = [arr[j], arr[i]]
}
return _arr
}
// 去抖
function debounce (func, delay) {
let timer
return function (...args) {
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
func.apply(this, args)
}, delay)
}
}
function insertArray (arr, val, compare, maxLen) {
const index = arr.findIndex(compare) //compare为一个比较函数
if (index === 0) { // 为0表示就在当前第一位
return
}
if (index > 0) { // 如果存在则删除
arr.splice(index, 1)
}
arr.unshift(val) // 在首位添加
if (maxLen && arr.length > maxLen) { // 大于最大值就删除末位
arr.pop()
}
}
function deleteFromArray (arr, compare) {
const index = arr.findIndex(compare)
if (index > -1) {
arr.splice(index, 1)
}
}
// 列表对比
// o中存在,但在p中不存在的算删除
// p中存在,o中不存在算新增
// name不同视为新增
// name相同,path不同视为编辑
// 都一样视为没有改动
// let o = [
// { name: 'a', path: '/aa' },
// { name: 'b', path: '/bb' },
// { name: 'c', path: '/c' },
// { name: 'e', path: '/e' },
// ];
// let p = [
// { name: 'a', path: '/aaa' },
// { name: 'bb', path: '/bb' },
// { name: 'c', path: '/c' },
// { name: 'd', path: '/dd' },
// ];
// 生成:
// let newList = [
// { name: 'bb', path: '/bb' },
// { name: 'd', path: '/dd' },
// ];
// let delList = [
// { name: 'b', path: '/bb' },
// { name: 'e', path: '/e' },
// ];
// let modifyList = [
// { name: 'a', path: '/aaa' },
// ];
// let unchangeList = [
// { name: 'c', path: '/c' },
// ];
// console.log(p.filter(it => o.every(item => item.name !== it.name))); // newList
// console.log(o.filter(it => p.every(item => item.name !== it.name))); // delList
// console.log(p.filter(it => o.some(item => item.name === it.name && item.path !== it.path))); // modifyList
// console.log(p.filter(it => o.some(item => item.name === it.name && item.path === it.path))); // unChangeList
let newList = [];
let delList = [];
let modifyList = [];
let unchangeList = [];
// hash表
let oHash = {};
o.forEach(item => {
oHash[item.name] = item;
});
p.forEach(item => {
let it = oHash[item.name];
if (!it) {
newList.push(item);
return;
}
delete oHash[item.name];
if (item.name === it.name && item.path === it.path) {
unchangeList.push(it);
return;
}
modifyList.push(item);
});
Object.keys(oHash).forEach(key => {
delList.push(Object.assign({}, oHash[key], { state: 'delete' }));
});
正则表达式
// 邮箱
var reg = /^[A-Za-z\d]+([-_.][A-Za-z\d]+)*@([A-Za-z\d]+[-.])+[A-Za-z\d]{2,4}$/;
dom操作
export function createDom(tpl) {
let container = document.createElement('div');
container.innerHTML = tpl;
return container.childNodes[0];
};
export function addEvent(el, type, fn, capture) {
el.addEventListener(type, fn, !!capture);
};
export function removeEvent(el, type, fn, capture) {
el.removeEventListener(type, fn, !!capture);
};
export function hasClass(el, className) {
let reg = new RegExp('(^|\\s)' + className + '(\\s|$)');
return reg.test(el.className);
};
export function addClass(el, className) {
if (hasClass(el, className)) {
return;
}
let newClass = el.className.split(' ');
newClass.push(className);
el.className = newClass.join(' ');
};
export function removeClass(el, className) {
if (!hasClass(el, className)) {
return;
}
let reg = new RegExp('(^|\\s)' + className + '(\\s|$)', 'g');
el.className = el.className.replace(reg, ' ');
};
JSON解析
1.eval()方法
var data = " // json字符串
{
root:
[
{name:'1',value:'0'},
{name:'6101',value:'北京市'},
{name:'6102',value:'天津市'},
{name:'6103',value:'上海市'},
{name:'6104',value:'重庆市'},
{name:'6105',value:'渭南市'},
{name:'6106',value:'延安市'},
{name:'6107',value:'汉中市'},
{name:'6108',value:'榆林市'},
{name:'6109',value:'安康市'},
{name:'6110',value:'商洛市'}
]
}";
var dataObj=eval("("+data+")"); // 转换为json对象
2.对于服务器返回的JSON字符串,如果jQuery异步请求将type(一般为这个配置属性)设为“json”,或者利 用.getJSON方法为例说明数据处理方法:
$.getJSON("http://www.phpzixue.cn/",{param:"gaoyusi"},function(data){
// 此处返回的data已经是json对象
3.使用Function对象来完成
var json='{"name":"CJ","age":18}';
data =(new Function("","return "+json))();
// 此时的data就是一个会解析成一个 json对象了.
CSS相关
垂直居中
<div class="block" style="height: 300px;">
<div class="centered">
<h3>haorooms案例题目</h3>
<p>haorooms案例内容,haorooms案例内haorooms案例内容</p>
</div>
</div>
// flex
.block{
display:flex;
align-items:center;/*垂直居中*/
justify-content: center;/*水平居中*/
width:100%;
height:100%;
background: #ddd
}
//伪类
.block{
&:before{
content: '';display: inline-block; height: 100%; vertical-align: middle;
}
.centered{
display: inline-block; vertical-align: middle; width: 50%;
}
}
1px线
border-top-1px($color)
&:before, &:after
display: block
position: absolute
border-top: 1px solid $color
left: 0
width: 100%
content: ' '
&:before
display: block
top: 0
&:after
display: none
bottom: 0
border-bottom-1px($color)
&:before, &:after
display: block
position: absolute
border-top: 1px solid $color
left: 0
width: 100%
content: ' '
&:before
display: none
top: 0
&:after
display: block
bottom: 0
flex
flex-box()
display: -ms-flexbox
display: -webkit-box
display: -webkit-flex
display: flex
flex()
-ms-flex: 1 1 0.000000001px
-webkit-box-flex: 1
-webkit-flex: 1
flex: 1
-webkit-flex-basis: 0.000000001px
flex-basis: 0.000000001px
width: 1%