# 常用微码
# JavaScript
# 文件大小计算
/**
* 文件大小计算
* size: 文件大小 byte
* result: 结果
*/
function getFileOfSize(size) {
var result = 0;
result = fileCalc(size, result);
size = (size / Math.pow(1024,result)).toFixed(2);
if (result == 1) {
return size+"K";
}else if (result == 2) {
return size+"M";
}else if (result == 3) {
return size+"G";
}
}
function fileCalc(size, result) {
result++;
size = (size / 1024).toFixed(2);
if (size > 1024) {
result = arguments.callee(size, result);
}
return result;
}
# UUID生成
function UUID(){
var d = new Date().getTime();
var uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = (d + Math.random()*16)%16 | 0;
d = Math.floor(d/16);
return (c=='x' ? r : (r&0x7|0x8)).toString(16);
});
return uuid;
}
# 获取URL参数
function getQueryString(key){
var reg = new RegExp("(^|&)"+key+"=([^&]*)(&|$)");
var result = window.location.search.substr(1).match(reg);
return result?decodeURIComponent(result[2]):null;
}
# JS数字转汉字
var chnNumChar = ["零", "一", "二", "三", "四", "五", "六", "七", "八", "九"];
var chnUnitSection = ["", "万", "亿", "万亿", "亿亿"];
var chnUnitChar = ["", "十", "百", "千"];
const SectionToChinese = section => {
var strIns = '', chnStr = '';
var unitPos = 0;
var zero = true;
while (section > 0) {
var v = section % 10;
if (v === 0) {
if (!zero) {
zero = true;
chnStr = chnNumChar[v] + chnStr;
}
} else {
zero = false;
strIns = chnNumChar[v];
strIns += chnUnitChar[unitPos];
chnStr = strIns + chnStr;
}
unitPos++;
section = Math.floor(section / 10);
}
return chnStr;
}
const NumberToChinese = num => {
var unitPos = 0;
var strIns = '', chnStr = '';
var needZero = false;
if (num === 0) {
return chnNumChar[0];
}
while (num > 0) {
var section = num % 10000;
if (needZero) {
chnStr = chnNumChar[0] + chnStr;
}
strIns = SectionToChinese(section);
strIns += (section !== 0) ? chnUnitSection[unitPos] : chnUnitSection[0];
chnStr = strIns + chnStr;
needZero = (section < 1000) && (section > 0);
num = Math.floor(num / 10000);
unitPos++;
}
return chnStr;
}
module.exports = {
NumberToChinese: NumberToChinese
}
# 有序数组插入数字
function insertNumber(arr, x) {
//查找到第一个大于x的数字
let b = newArr.find(e => e > x);
if (b === undefined) {
// 如果b不存在,证明x是最大的数字,push到数组尾部
newArr.push(x);
} else {
//获取b的index,把新的数字插入到b的位置
let bIndex = newArr.indexOf(b)
newArr.splice(bIndex, 0, x)
}
return arr;
}
# 两个有序数组合并成一个新的有序数组
function insert_some_numbers(arr1, arr2) {
//创建新数组,并结构第一个数组
var newArr = [...arr1];
for (var i = 0; i < arr2.length; i++) {
//获取第二个数组中的每一位
x = arr2[i];
//在新解构的数组中查找第一个比他大的数组
let b = newArr.find(e => e > x);
//获取到这个数字的索引并插入到他的前面
let bindex = newArr.indexOf(b)
newArr.splice(bindex === -1 ? newArr.length : bindex, 0, x)
}
return newArr;
}
let arr1 = [1, 2, 3, 4, 5, 6, 8, 9];
console.log(insert_some_numbers(arr1, [1, 2, 3]));
# 二分查找
function binarySearch(arr, x) {
var left = 0; //左边界
var right = arr.length - 1; //右边界
var guess; // 游标, 中间索引去小数点
while (left <= right) { // 左侧边界小于右侧边界才执行
guess = ((left + right) / 2) | 0; //游标索引, 中间索引去小数点
if (arr[guess] === x) return guess // 当游标索引就是查找的X的话,返回游标索引
else if (arr[guess] > x) right = guess - 1 // 游标索引位 大于 x , 右边界移动到guess之前。
else left = guess + 1 // 游标索引位 小于 x , 右边界移动到guess之后。
}
return -1; //未查找到
}
var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
console.log(
binarySearch(arr, 5)
)
# 有序数组插入新数字
- 模拟一个空位置循环比较
- 从数组尾部向前比较,前面的那一位比x大,比x大的那个数字索引+1
- 再跟前面的一位作比较,如果比X小, p+1位索引就被变量x 占了
function insert_number_3(arr, x) {
//p是下一个待比较元素的索引
//p-1是空位
//p不能小于0, 当P小于0代表, x是最小的
let p = arr.length - 1;
while (p >= 0 && arr[p] > x) {
arr[p + 1] = arr[p];
p--;
}
arr[p + 1] = x;
}
let arr1 = [1, 2, 3, 4, 5, 6, 8, 9];
insert_number_3(arr1, 6)
console.log(arr1)
# 插入排序
function insertion_sort(arr) {
//第一位不用去作比较,只有一位的数组可以看作为有序数组
for (var i = 1; i < arr.length; i++) {
insert(arr, i, arr[i]);
}
}
function insert(arr, i, x) {
let p = i - 1; // p 作为被首先比较的元素
// arr[i] 也就是 x 是待插入的元素
while (p >= 0 && arr[p] > x) {
// 当待插入的元素
arr[p + 1] = arr[p];
p--;
}
arr[p + 1] = x;
}
# 选择排序
// 找到第一个最小的,放在第一位
// 再找到第二个最小的, 放在第二位
function select(array) {
var len = array.length;
//第零位到倒数第二位
for (var i = 0; i < len - 1; i++) {
//先认定数组中的第i位是最小的, 再逐次跟后面的作比较
var minnum = array[i];
//第一位到最后一位
for (var j = i + 1; j < len; j++) {
// 如果后面的更小的话, 做值的交换
if (array[j] < minnum) {
//值交换
[array[j], minnum] = [minnum, array[j]]
}
}
//比较过后, 给第i位赋值
array[i] = minnum;
}
}
var arr = [4, 5, 8, 9, 4, 2, 15, 6]
select(arr)
console.log(arr)
# 冒泡排序
- 先找出最大的,再找出最小的
- 性能最差
- 排序次数: arr.length的等差数列求和次 -> n**n/2 -n/2 次
function bubble_sort(arr) {
//值交换函数
function swap(arr, x, j) {
[arr[x],arr[j]] = [arr[j], arr[i]]
}
//先找出最大的,再找出最小的
for (let i = arr.length - 1; i >= 1; i--) {
//从1开始,每一次都和前一位作比较。
for (let j = 1; j <= i; j++) {
arr[j] < arr[j - 1] && swap(arr, j-1, j)
}
}
}
const arr2 = [91, 60, 96, 9, 30, 20, 31, 77, 81, 24];
bubble_sort(arr2)
console.log(arr2);
# 合并排序
//将数组分成两个数组,
// 索引 [a,b) 和 [b,c)
//合并函数部分,
function merge(arr, a, b, c) {
// 此时arr1 和 arr2 是 两个有序数组
let arr1 = arr.slice(a, b);
let arr2 = arr.slice(b, c);
//在两个数组后面布置哨兵
arr1.push(Infinity);
arr2.push(Infinity);
//设置两个数组的比较位置的索引的游标索引
// 如果这个数字被赋值,则索引+1
var i = 0, j = 0;
//循环给arr赋值
for (let k = a; k < c; k++) {
//k : 下一个写入位置
//i : arr1中的回写位置
//j : arr2中的回写位置
arr[k] = arr1[i] < arr2[j] ? arr1[i++] : arr2[j++];
}
}
function mergeSort(arr, a, c) {
//判断数组长度是否为1
if (c - a < 2) { return };
const b = Math.ceil((a + c) / 2);
//左侧部分递归
mergeSort(arr, a, b);
//右侧部分递归
mergeSort(arr, b, c);
//执行拼接
merge(arr, a, b, c);
}
// 把数组拆成一个,一个的数组, 在执行拼接
# 双路快速
function quickSort(arr) {
//递归出口,数组长度为0
if (arr.length == 0) return [];
// 建立比较数字, 左侧数组, 右侧数组
var left = [];
var right = [];
var pivot = arr[0];
//从数组第一位开始比较
for (var i = 1; i < arr.length; i++) {
if (arr[i] < pivot) {
left.push(arr[i]);
} else {
right.push(arr[i]);
}
}
// 递归 连接数组, 这个函数是纯函数,结果不会改变原数组。
return quickSort(left).concat(pivot, quickSort(right))
}
let arr = [4, 51, 59, 13, 1, 31, 3, 1, 8];
let result = quickSort(arr);
console.log(result)
# 三路快排
function qSort3(arr) {
if (arr.length == 0) {
return [];
}
//定义三个数组
var left = [];
//三路快排的核心是多了一个中间数组, 中间数组放相等的值,避免了不必要的比较
var center = [];
var right = [];
//设置一个比较值
var pivot = arr[0];
//循环比较部分
for (var i = 0; i < arr.length; i++) {
if (arr[i] < pivot) {
left.push(arr[i]);
} else if (arr[i] == pivot) {
center.push(arr[i]);
} else {
right.push(arr[i]);
}
}
//循环递归 大于比较值的部分和小于比较值的部分
return [...qSort3(left), ...center, ...qSort3(right)];
}
var newArr = qSort3([9, 4, 10, 8, 12, 2, 6, 7, 3, 1, 1, 0, 9, 1, 0])
console.log(newArr)
# 深度克隆
function deepClone2(origin, target) {
var target = target || ((origin instanceof Array) ? [] : {});
for (var prop in origin) {
if (origin.hasOwnProperty(prop)) {
if (typeof origin[prop] == 'object') {
if (Object.prototype.toString.call(origin[prop]) === '[object Array]') {
target[prop] = [];
} else {
target[prop] = {};
}
deepClone2(origin[prop], target[prop]);
} else {
target[prop] = origin[prop]
}
}
}
return target;
}
# 数组扁平化
function platArray(arr) {
var newArr = [];
function pushToArray(arr) {
for (var i = 0; i < arr.length; i++) {
if (arr[i] instanceof Array) {
pushToArray(arr[i])
} else {
newArr.push(arr[i])
}
}
}
pushToArray(arr)
return newArr;
}
console.log(platArray([[1, 2], [[[[3]]]], [{ name: "lyz", info: { age: "24" } }], [4, [5, [6]]]]));
// [1, 2, 3, { name: 'lyz', info: { age: '24' } }, 4, 5, 6]
# 字符串反转
var str = 'abcde';
function strReverse(str) {
// new String 出来的类数组是不能修改某一位的,
// writeable是false;
var strObj = [...new String(str)];
var times = strObj.length / 2 | 0;
for (var i = 0; i < times; i++) {
var y = strObj.length - 1 - i;
[strObj[i], strObj[y]] = [strObj[y], strObj[i]];
}
return strObj.join('');
}
console.log(strReverse(str));
# 简易Promise
//executor 函数是同步执行的函数 ,包含有两个参数 resolve reject
// promise对象有三种状态 pending, fulfilled 和 rejected
function myPromise(executor) {
//在 es5中函数中执行函数的this指向问题
var _this = this;
// 设置初始状态和resolve和reject函数初始参数
_this.status = "pending";
_this.resolveValue = null;
_this.rejectValue = null;
function resolve(value) {
if (_this.status === 'pending') {
_this.status = "fulfilled";
_this.resolveValue = value;
}
}
function reject(reason) {
if (_this.status === 'pending') {
_this.status = "rejected";
_this.rejectValue = reason;
}
}
//使用try catch来处理Promise中抛出异常的情况
try {
executor(resolve, reject)
} catch (e) {
//如果抛出异常 , 执行reject就可以了
reject(e)
}
}
//Promise原型链上的方法then的实现
myPromise.prototype.then = function (onFulfilled, onRejected) {
var _this = this;
if (_this.status === "fulfilled") {
onFulfilled(_this.resolveValue)
}
if (_this.status === "rejected") {
onRejected(_this.rejectValue)
}
}
# 异步的简易版Promise
//executor 函数是同步执行的函数 ,包含有两个参数 resolve reject
// promise对象有三种状态
// pending, fulfilled 和 rejected
function myPromise(executor) {
//在 es5中函数中执行函数的this指向问题
var _this = this;
// 设置初始状态和resolve和reject函数初始参数
_this.status = "pending";
_this.resolveValue = null;
_this.rejectValue = null;
//执行数组, 里面存入函数
_this.ResolveCallbackList = [];
_this.RejectCallbackList = [];
function resolve(value) {
if (_this.status === 'pending') {
_this.status = "fulfilled";
_this.resolveValue = value;
//执行的时候已经可以是异步了, 如果是异步的时候,
//数组里面有函数,不然没有函数
_this.ResolveCallbackList.forEach(function (ele) {
ele();
})
}
}
function reject(reason) {
if (_this.status === 'pending') {
_this.status = "rejected";
_this.rejectValue = reason;
//执行的时候已经可以是异步了, 如果是异步的时候,
//数组里面有函数,不然没有函数
_this.RejectCallbackList.forEach(function (ele) {
ele();
})
}
}
//使用try catch来处理Promise中抛出异常的情况
try {
executor(resolve, reject)
} catch (e) {
//如果抛出异常 , 执行reject就可以了
reject(e)
}
}
//Promise原型链上的方法then的实现
myPromise.prototype.then = function (onFulfilled, onRejected) {
var _this = this;
if (_this.status === "fulfilled") {
onFulfilled(_this.resolveValue)
}
if (_this.status === "rejected") {
onRejected(_this.rejectValue)
}
//增加pending状态的判断, 如果是pending, 存入到相应的执行事件的数组当中。
if (_this.status === "pending") {
onFulfilled && _this.ResolveCallbackList.push(function () {
onFulfilled(_this.resolveValue);
});
onRejected && _this.RejectCallbackList.push(function () {
onRejected(_this.rejectValue);
})
}
}
# Promise.all
MyPromise.all = function(promises) {
return new Promise(function (resolve, reject) {
//类型判断
if (!isArray(promises)) {
return reject(new TypeError('arguments must be an array'));
}
//目前已经resolve的数量
var resolvedCounter = 0;
//获取参数数组长度
var promisesNum = promises.length;
// 全部成功是的返回值是一个数组,数组里面是每一个成功的promise的resolve的参数
var resolvedValues = new Array(promiseNum);
//对数组进行遍历,因为是异步,所以要防止产生闭包。
for (var i = 0; i < promiseNum; i++) {
(function (i) {
Promise.resolve(promises[i]).then(function (value) {
resolvedCounter++
resolvedValues[i] = value
// 只有resolve的数量和promise的数量一致的时候才会触发最外层的resolve执行
if (resolvedCounter == promisesNum) {
return resolve(resolvedValues)
}
}, function (reason) {
return reject(reason)
})
})(i)
}
})
}
# 解构原始数据
const rawUser = {
name: 'John',
surname: 'Doe',
email: 'john@doe.com',
displayName: 'SuperCoolJohn',
joined: '2016-05-05',
image: 'path-to-the-image',
followers: 45
...
}
//提取出两个部分,分别是用户及用户信息
let user = {}, userDetails = {};
({ name: user.name, surname: user.surname, ...userDetails } = rawUser);
console.log(user); // outputs { name: "John", surname: "Doe" }
console.log(userDetails); // outputs { email: "john@doe.com", displayName: "SuperCoolJohn", joined: "2016-05-05", image: "path-to-the-image", followers: 45 }
# 动态属性名
const dynamic = 'email';
let user = {
name: 'John',
[dynamic]: 'john@doe.com'
}
console.log(user); // outputs { name: "John", email: "john@doe.com" }
# CSS
# 超过2行显示点点点
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
# 空心箭头
.u-arrow {
display: inline-block;
width: 10px;
height: 10px;
border-top: 2px solid #62B4FB;
border-right: 2px solid #62B4FB;
}
.u-arrow-up {
margin: 0 0 -2px 5px;
transform: rotate(-45deg);
}
.u-arrow-down {
margin: 0 0 2px 5px;
transform: rotate(135deg);
}
.u-arrow-left {
transform: rotate(-135deg);
}
.u-arrow-right {
transform: rotate(45deg);
}
# 爱心
#heart {
position: relative;
width: 100px;
height: 90px;
}
#heart:before,
#heart:after {
position: absolute;
content: "";
left: 50px;
top: 0;
width: 50px;
height: 80px;
background: red;
border-radius: 50px 50px 0 0;
transform: rotate(-45deg);
transform-origin: 0 100%;
}
#heart:after {
left: 0;
transform: rotate(45deg);
transform-origin: 100% 100%;
}
# 太极
#yin-yang {
width: 96px;
box-sizing: content-box;
height: 48px;
background: #eee;
border-color: red;
border-style: solid;
border-width: 2px 2px 50px 2px;
border-radius: 100%;
position: relative;
}
#yin-yang:before {
content: "";
position: absolute;
top: 50%;
left: 0;
background: #eee;
border: 18px solid red;
border-radius: 100%;
width: 12px;
height: 12px;
box-sizing: content-box;
}
#yin-yang:after {
content: "";
position: absolute;
top: 50%;
left: 50%;
background: red;
border: 18px solid #eee;
border-radius: 100%;
width: 12px;
height: 12px;
box-sizing: content-box;
}
# 放大镜
#magnifying-glass {
font-size: 10em;
display: inline-block;
width: 0.4em;
box-sizing: content-box;
height: 0.4em;
border: 0.1em solid red;
position: relative;
border-radius: 0.35em;
}
#magnifying-glass:before {
content: "";
display: inline-block;
position: absolute;
right: -0.25em;
bottom: -0.1em;
border-width: 0;
background: red;
width: 0.35em;
height: 0.08em;
transform: rotate(45deg);
}
# 锁
#lock {
font-size: 8px;
position: relative;
width: 18em;
height: 13em;
border-radius: 2em;
top: 10em;
box-sizing: border-box;
border: 3.5em solid red;
border-right-width: 7.5em;
border-left-width: 7.5em;
margin: 0 0 6rem 0;
}
#lock:before {
content: "";
box-sizing: border-box;
position: absolute;
border: 2.5em solid red;
width: 14em;
height: 12em;
left: 50%;
margin-left: -7em;
top: -12em;
border-top-left-radius: 7em;
border-top-right-radius: 7em;
}
#lock:after {
content: "";
box-sizing: border-box;
position: absolute;
border: 1em solid red;
width: 5em;
height: 8em;
border-radius: 2.5em;
left: 50%;
top: -1em;
margin-left: -2.5em;
}
# 小程序重置button样式
button {
margin: 0;
padding: 0;
background-color: transparent;
line-height: inherit;
border-radius: 0;
border: none;
}
button::after{
border: none;
}
# vue
# 识别ie浏览器
/**
* 识别ie--浅识别
*/
export const isIe = () => {
let explorer = window.navigator.userAgent;
//判断是否为IE浏览器
if (explorer.indexOf("MSIE") >= 0) {
return true;
}else {
return false
}
}
# 颜色16进制转rgba
/**
* 颜色转换16进制转rgba
* @param {String} hex
* @param {Number} opacity
*/
export function hex2Rgba(hex, opacity) {
if(!hex) hex = "#2c4dae";
return "rgba(" + parseInt("0x" + hex.slice(1, 3)) + "," + parseInt("0x" + hex.slice(3, 5)) + "," + parseInt("0x" + hex.slice(5, 7)) + "," + (opacity || "1") + ")";
}
# 去除html标签
// 去除html标签
export const htmlSafeStr = (str) => {
return str.replace(/<[^>]+>/g, "")
}
# 获取url参数对象
/* 获取url参数 */
export const getQueryString = () => {
let qs = location.href.split('?')[1] || '',
args = {},
items = qs.length ? qs.split("&") : [];
items.forEach((item,i) => {
let arr = item.split('='),
name = decodeURIComponent(arr[0]),
value = decodeURIComponent(arr[1]);
name.length && (args[name] = value)
})
return args;
}
# 解析url参数
/* 解析url参数 */
export const paramsToStringify = (params) => {
if(params){
let query = [];
for(let key in params){
query.push(`${key}=${params[key]}`)
}
return `${query.join('&')}`
}else{
return ''
}
}
# 数据转化为数组
export const toArray = (data) => {
return Array.isArray(data) ? data : [data]
}
# 带参数跳转url(hash模式)
/**
* 带参数跳转url(hash模式)
* @param {String} url
* @param {Object} params
*/
export const toPage = (url, params) => {
if(params){
let query = [];
for(let key in params){
query.push(`${key}=${params[key]}`)
}
window.location.href = `./index.html#/${url}?${query.join('&')}`;
}else{
window.location.href = `./index.html#/${url}`;
}
}
# 控制字符串显示,超出指定字数则显示省略号
/**
* 指定字符串 溢出显示省略号
* @param {String} str
* @param {Number} num
*/
export const getSubStringSum = (str = "", num = 1) => {
let newStr;
if(str){
str = str + '';
if (str.trim().length > num ) {
newStr = str.trim().substring(0, num) + "...";
} else {
newStr = str.trim();
}
}else{
newStr = ''
}
return newStr;
}
# 生成uuid
/**
* 生成uuid
* @param {number} len 生成指定长度的uuid
* @param {number} radix uuid进制数
*/
export function uuid(len, radix) {
let chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
let uuid = [], i;
radix = radix || chars.length;
if (len) {
for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random()*radix];
} else {
let r;
uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
uuid[14] = '4';
for (i = 0; i < 36; i++) {
if (!uuid[i]) {
r = 0 | Math.random()*16;
uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
}
}
}
return uuid.join('');
}
# 生成指定格式的时间字符串
/**
* 生成指定格式的时间
* @param {*} timeStemp 时间戳
* @param {*} flag 格式符号
*/
export function formatTime(timeStemp, flag) {
let time = new Date(timeStemp);
let timeArr = [time.getFullYear(), time.getMonth() + 1, time.getDate()];
return timeArr.join(flag || '/')
}