前言
作为一名前端攻城狮,记录下一些常用的方法是必不可少了。以下记录我遇到经常用到的知识。
有更好的方法及先进的技术请务必告诉下我。
目录
三、图片--url格式和base64格式和blob格式的互转
一、时间格式化
/*
* 时间格式化
* @method GetDateTime
* @param {Object} dateObj 时间对象 new Date()
* @param {string} format 格式 例如 'Y-m-d h:i:s'
* @return {string}
*/
function GetDateTime (dateObj, format) {
if (dateObj) {
if (typeof (dateObj) === 'string') {
var tempIndex = dateObj.lastIndexOf('.');
if (tempIndex > -1) {
dateObj = dateObj.substring(0, tempIndex);
}
dateObj = dateObj.replace('T', ' ').replace(/\-/g, "/");
}
var date = new Date(dateObj);
var obj = {
y: date.getFullYear(),
m: date.getMonth() + 1,
d: date.getDate(),
h: date.getHours(),
min: date.getMinutes(),
s: date.getSeconds()
}
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
var element = obj[key];
obj[key] = element < 10 ? '0' + element : element;
}
}
if (format) {
return format.replace('Y', obj.y)
.replace('m', obj.m)
.replace('d', obj.d)
.replace('h', obj.h)
.replace('i', obj.min)
.replace('s', obj.s)
}
return obj.y + '-' + obj.m + '-' + obj.d + ' ' + obj.h + ':' + obj.min + ':' + obj.s; //返回时间格式
} else
return ''
}
GetDateTime(new Date());//"2019-02-27 10:33:58"
二、JSON与URL参数的互转
1.json转url参数
/*
* json转url参数
* @method parseParams
* @param {Object} data json数据
* @return {String} 序列化后的字符串
*/
function parseParams(data) {
try {
var tempArr = [];
for (var i in data) {
var key = encodeURIComponent(i);
var value = encodeURIComponent(data[i]);
tempArr.push(key + '=' + value);
}
var urlParamsStr = tempArr.join('&');
return urlParamsStr;
} catch (err) {
return '';
}
}
var obj = {
name: 'zhangsan',
age: 100
};
parseParams(obj); //"name=zhangsan&age=100"
2.url转json
/*
* url转json
* @method getParams
* @param {String} url url数据
* @return {Object} 转化后的json格式
*/
function getParams(url) {
try {
var index = url.indexOf('?');
if(index !== -1) {
url = url.match(/\?([^#]+)/)[1];
}
var obj = {}, arr = url.split('&');
for (var i = 0; i < arr.length; i++) {
var subArr = arr[i].split('=');
obj[subArr[0]] = subArr[1];
}
return obj;
} catch (err) {
return null;
}
}
var urlStr = 'http://www.xxx.com/test?name=zhangshan&age=100#hello';
var urlStr2 = 'name=zhangshan&age=100';
getParams(urlStr); //{name: "zhangshan", age: "100"}
getParams(urlStr2); //{name: "zhangshan", age: "100"}
三、图片--url格式和base64格式和blob格式的互转
1.url转base64
/*
* url转base64格式
* @method urlToBase64
* @param {String} url 图片的url地址
* @return {String} 转化后的base64格式
*/
function urlToBase64(url) {
return new Promise ((resolve,reject) => {
let image = new Image();
image.onload = function() {
let canvas = document.createElement('canvas');
canvas.width = this.naturalWidth;
canvas.height = this.naturalHeight;
// 将图片插入画布并开始绘制
canvas.getContext('2d').drawImage(image, 0, 0);
// result
let result = canvas.toDataURL('image/png')
resolve(result);
};
// CORS 策略,会存在跨域问题https://stackoverflow.com/questions/20424279/canvas-todataurl-securityerror
image.setAttribute("crossOrigin",'Anonymous');
image.src = url;
// 图片加载失败的错误处理
image.onerror = () => {
reject(new Error('图片流异常'));
}
})
}
let imgUrL = '图片地址';
urlToBase64(imgUrL).then(res => {
// 转化后的base64图片地址
console.log('base64', res)
})
2.base64转url
base64转url
base64可直接作为img的src
3.base64转blob
/*
* base64转blob
* @method base64ToBlob
* @param {String} dataURI base64数据
* @return {blob} blob格式
*/
function dataURItoBlob(dataURI) {
var mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0]; // mime类型
var byteString = atob(dataURI.split(',')[1]); //base64 解码
var arrayBuffer = new ArrayBuffer(byteString.length); //创建缓冲数组
var intArray = new Uint8Array(arrayBuffer); //创建视图
for (var i = 0; i < byteString.length; i++) {
intArray[i] = byteString.charCodeAt(i);
}
return new Blob([intArray], {type: mimeString});
}
var dataURI = 'base64';
dataURItoBlob(dataURI);
4.blob转base64
/*
* blob转base64
* @method blobToDataURI
* @param {blob} blob blob格式
* @return {String} 转化后的base64格式
*/
function blobToDataURI(blob) {
return new Promise(function(resolve){
var reader = new FileReader();
reader.onload = function (e) {
resolve(e.target.result);
}
reader.readAsDataURL(blob);
})
}
var blob = 'blob';
blobToDataURI(blob).then(dataURI => {
console.log(dataURI)
})
5.url转blob
/*
* url转blob格式
* @method urlToBase64
* @param {String} url 图片的url地址
* @return {Blob} 转化后的blob对象
*/
function urlToBlob(url) {
return new Promise ((resolve,reject) => {
let image = new Image();
image.onload = function() {
let canvas = document.createElement('canvas');
canvas.width = this.naturalWidth;
canvas.height = this.naturalHeight;
// 将图片插入画布并开始绘制
canvas.getContext('2d').drawImage(image, 0, 0);
canvas.toBlob(function(result){
resolve(result);
})
};
// CORS 策略,会存在跨域问题https://stackoverflow.com/questions/20424279/canvas-todataurl-securityerror
image.setAttribute("crossOrigin",'Anonymous');
image.src = url;
// 图片加载失败的错误处理
image.onerror = () => {
reject(new Error('图片流异常'));
}
})
}
var imgUrL = '图片地址';
urlToBlob(imgUrL).then(blob => {
console.log(blob);
})
6.blob转url
var blob = 'blob';
window.URL.createObjectURL(blob);//返回结果直接作为img的src
四、cookie操作
1.设置cookie
/**
* 设置cookie
* @method setCookie
* @param {String} cname 键
* @param {String} cvalue 值
* @param {Number} exdays 过期时间,毫秒
* @returns {undefined}
*/
function setCookie(cname,cvalue,exdays){
var d = new Date();
d.setTime(d.getTime()+exdays);
var expires = "expires="+d.toGMTString();
document.cookie = cname + '=' + cvalue + '; ' + expires + ';path=/';
}
setCookie('key','val',1000 * 60 * 60);//一小时后过期
2.获取cookie
/**
* 获取cookie
* @method getCookie
* @param {String} cname 键
* @returns {String}
*/
function getCookie(cname){
var name = cname + "=";
var ca = document.cookie.split(';');
for(var i=0; i<ca.length; i++) {
var c = ca[i].trim();
if (c.indexOf(name)==0) { return c.substring(name.length,c.length); }
}
return null;
}
getCookie('key');
五、对象的深拷贝
/**
* 深拷贝
* @method copy
* @param {Object} obj1 需要copy的对象
* @returns {String}
*/
function copy(obj1){//复制obj1
if(typeof obj1==='object'){//先判断传来的是不是数组或者对象
var obj2=obj1 instanceof Array?[]:{};//判断是数组还是对象
for(var i in obj1){
if(typeof obj1[i]==='object'){//如果值是对象或者数组
obj2[i]=copy(obj1[i]);//递归调用
}else{
obj2[i]=obj1[i];//直接赋值
}
}
return obj2;
}else{
return obj1;
}
}
var obj1={
name:'user1',
say:[0,1,2,3],
data:{
age:20,
sex:['man','woman']
}
};
var obj2=copy(obj1);
console.log(obj1.data.sex[0]);//man
console.log(obj2.data.sex[0]);//man
obj2.data.sex[0]='neutral';
console.log(obj1.data.sex[0]);//man
console.log(obj2.data.sex[0]);//neutral
六、前端图片压缩
/*
* url转base64格式
* @method urlToBase64
* @param {String} url 图片的url地址,可传图片路径,base64,blbo格式.
* @param {Object} options {
* width:宽度,默认原始宽度,
* height:高度,未指定时自动计算高度
* quality:压缩质量,默认0.92 取值 0~1
* type: 压缩后图片类型, 默认'image/jpeg'
* }
* @return {String} 转化后的base64格式
*/
function compress(url, options={}) {
return new Promise ((resolve,reject) => {
if(Object.prototype.toString.call(url) === '[object Blob]') url = window.URL.createObjectURL(url);
if(Object.prototype.toString.call(options) !== '[object Object]') reject('请传入有效参数');
let image = new Image();
image.onload = function() {
options = {
width: options.width || this.width,
height: options.height || this.height * (options.width || this.width) / this.width,
quality: (isNaN(options.quality) || options.quality < 0 || options.quality>1) ? 0.92 : options.quality,
type: options.type || 'image/jpeg'
}
let canvas = document.createElement('canvas');
canvas.width = options.width;
canvas.height = options.height;
// 将图片插入画布并开始绘制
canvas.getContext('2d').drawImage(image, 0, 0, canvas.width, canvas.height);
// result
let result = canvas.toDataURL(options.type, options.quality)
resolve(result);
};
// CORS 策略,会存在跨域问题https://stackoverflow.com/questions/20424279/canvas-todataurl-securityerror
image.setAttribute("crossOrigin",'Anonymous');
image.src = url;
// 图片加载失败的错误处理
image.onerror = () => {
reject(new Error('图片流异常'));
}
})
}
let imgUrL = 'http://p2.music.126.net/FWiFOXMnLcc_rR8_FAWTgQ==/109951163919100565.jpg';
compress(imgUrL,{width:110}).then(res => {
// 转化后的base64图片地址
console.log('base64', res)
})
七、函数的节流和防抖
函数节流:当连续触发函数时,函数在n秒内只会执行一次.
函数防抖:函数频繁触发的情况下,只有函数触发的间隔超过指定间隔的时候,函数才会执行
节流
/*
* 函数节流
* @method debounce
* @param {funciton} fn 需要执行的函数
* @param {Number} wait 需要等待的时间,毫秒
* @returns {undefined}
*/
function debounce(fn,wait){
var timeout;
return function(){
var context=this;
var args=arguments;
if(!timeout){
timeout=setTimeout(function(){
timeout=null;
fn.apply(context,args);
},wait)
}
}
}
防抖
/*
* 函数防抖
* @method debounce
* @param {funciton} fn 需要执行的函数
* @param {Number} wait 需要等待的时间,毫秒
* @returns {undefined}
*/
function debounce(fn,wait){
var timeout;
return function(){
var context=this;
var args=arguments;
if(timeout) clearTimeout(timeout);
timeout=setTimeout(function(){
fn.apply(context,args);
},wait)
}
}
八、call,apply,bind的实现原理
call的实现原理
Function.prototype.call2=function(content){
// 在对象身上绑定函数,使this指向改对象
content.fn=this;
//储存参数
var args=[];
for(var i=1,len=arguments.length;i<len;i++){
args.push(arguments[i]);
}
//执行该函数
var str="content.fn("+args+")";
eval(str);
//清空函数
content.fn=null;
}
apply的实现原理
Function.prototype.apply2=function(content){
// 在对象身上绑定函数,使this指向改对象
content.fn=this;
//储存参数
var args=arguments[1];
//执行该函数
var str="content.fn("+args+")";
eval(str);
//清空函数
content.fn=null;
}
bind的实现原理
Function.prototype.bind2=function(content){
//保存当前this;
var that=this;
return function(){
// 在对象身上绑定函数,使this指向改对象
content.fn=that;
// //执行该函数
var str="content.fn("+Array.from(arguments)+")";
eval(str);
content.fn=null;
}
}
九、Event loop
js同步和异步,宏任务和微任务
//求以下代码输入结果
setTimeout(function(){
console.log('1')
});
new Promise(function(resolve){
console.log('2');
resolve();
}).then(function(){
console.log('3')
});
console.log('4');
结果 2,4,3,1
首先执行setTimeout,将回调放入宏任务eventqueue中,再执行promise,立即输入2,
将then方法放入微任务的eventqueue中,立即输入4,同步任务执行完毕,开始执行异步任务
先执行异步微任务eventqueue,输入3,再执行异步宏任务输入1,以此循环;
总结:
1.先执行同步任务,再执行异步任务,
2.当同步任务执行完毕后,先执行微任务回调,再执行宏任务回调,
3.当异步任务执行完毕后,再执行同步任务,事件循环.
十、闭包
闭包就是能够读取其他函数内部变量的函数。
function fn(){
var a=1;
function b(){
a++;
console.log(a);
}
return b;
}
var c=fn();//通过闭包访问fn内部变量c的值并储存
c();//实际调用b();输出2
c();//输出3,可以储存a的值并改变
十一、原型
我另外写了一篇文章,传送门
十二、jsonp
实现原理:动态创建script标签将src设置为请求地址,并且带上参数callback(通常为callback,其实主要看服务端怎么写的),服务端去执行这个函数,并传入返回数据。
jsonp请求
//动态创建script标签
var script = document.createElement("script");
地址为请求地址,带上回调函数callback=jsonpCallback
script.src =url+'?callback=jsonpCallback';//带上回调函数
document.body.insertBefore(script, document.body.firstChild);
function jsonpCallback(res){
console.log(res);
}
服务端php示例
<?php
$data='我是jsonp的返回值';
if($_GET['callback']){//有callback表示jsonp请求
//执行这个函数,并传入数据.
echo "{$_GET['callback']}({$data})";
}else{
echo $data;
}
?>