在前端工作期间遇到过不少的问题,很多时候这些问题也是反复出现的,是时候将问题都记录下来,用于回顾及避免反复浪费时间在同一问题上。
1、对象转URL参数
var parseParam=function(param, key){
var paramStr="";
if(param instanceof String || param instanceof Number || param instanceof Boolean){
paramStr += "&" + key + "=" + encodeURIComponent(param);
}else{
$.each(param,function(i){
var k = key==null ? i : key + (param instanceof Array ? "["+i+"]" : "."+i);
paramStr += '&' + parseParam(this, k);
});
}
return paramStr.substr(1);
};
var a = {a: 'a', b: 'b'};
console.log(parseParam(a)); // a=a&b=b
console.log(parseParam(a, 'person')); // person.a=a&person.b=b
2、日期格式化
/**
* 对Date的扩展,将 Date 转化为指定格式的String
* 月(M)、日(d)、小时(h)、分(m)、秒(s)、季度(q) 可以用 1-2 个占位符,
* 年(y)可以用 1-4 个占位符,毫秒(S)只能用 1 个占位符(是 1-3 位的数字)
*
* (new Date()).Format("yyyy-MM-dd hh:mm:ss.S") ==> 2006-07-02 08:09:04.423
* (new Date()).Format("yyyy-M-d h:m:s.S") ==> 2006-7-2 8:9:4.18
*
* @param {*} fmt
*/
Date.prototype.Format = function (fmt) { //author: meizz
var o = {
"M+": this.getMonth() + 1, //月份
"d+": this.getDate(), //日
"h+": this.getHours(), //小时
"m+": this.getMinutes(), //分
"s+": this.getSeconds(), //秒
"q+": Math.floor((this.getMonth() + 3) / 3), //季度
"S": this.getMilliseconds() //毫秒
};
if (/(y+)/.test(fmt))
fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
for (var k in o)
if (new RegExp("(" + k + ")").test(fmt))
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
return fmt;
}
3、模板字符串实现
/**
* 模板字符串实现,将指定内容赋值给字符串中的参数字段
*
* var url = '../img/bookList/img_{0}.png';
* url.format('a1');
*
* @param {*} args
*/
String.prototype.format = function (args) {
var result = this;
if (arguments.length > 0) {
if (arguments.length == 1 && typeof (args) == "object") {
for (var key in args) {
if (args[key] != undefined) {
var reg = new RegExp("({" + key + "})", "g");
result = result.replace(reg, args[key]);
}
}
}
else {
for (var i = 0; i < arguments.length; i++) {
if (arguments[i] != undefined) {
var reg = new RegExp("({[" + i + "]})", "g");
result = result.replace(reg, arguments[i]);
}
}
}
}
return result;
};
4、文件下载
关于下载可以先阅读 https://www.cnblogs.com/husts...
a标签 & window.open()
// 浏览器支持能够打开的格式,他都会默认直接在线打开(比如word或图片),不支持的格式,他就会弹出下载提示。最好是做成.rar格式的文件
$btn.click(function(){window.open("xxxxx/file.rar");});
// 使用download属性
<a href="large.jpg" download>下载</a>
var isSupportDownload = 'download' in document.createElement('a'); // 监测当前浏览器是否支持download属性
Iframe
try {
requestTaskByForm();
startTask(translateResponse, 0, iInterval, iTimeout);
} catch (exp) {
console.err(exp);
}
// config 下载JSON报文配置项;timeout 超时(毫秒),默认60000;interval 轮询间隔(毫秒),默认100;callback 回调函数;err 异常回调;scope 作用域;url 下载servlet,默认cifjsondownload;
/*
* isArray
* @param v
* @returns {Boolean}
*/
function isArray(v){
return !!v && Object.prototype.toString.call(v) === '[object Array]';
};
/**
* isObject
* @param v
* @returns {Boolean}
*/
function isObject(v){
return !!v && Object.prototype.toString.call(v) === '[object Object]';
};
/**
* json object copy
* @param o
* @param c
*/
function apply(o,c){
if (isObject(c)) {
for (var p in c) {
if (o.hasOwnProperty(p.toString().toUpperCase()))
o[p.toString().toUpperCase()] = c[p];
if (o.hasOwnProperty(p))
o[p] = c[p];
}
}
};
/**
* parseJson
* @param message
*/
function parseJson(res){
return eval('(' + res + ')');
};
/**
* init json body
*/
function initJsonElements(){
apply(oCif, oConfig);
}
/**
* init html elements
*/
function initHtmlElements(){
requestDiv = document.getElementById(reqDivId);
if(!requestDiv){
requestDiv = document.createElement("div");
requestDiv.id = reqDivId;
requestDiv.innerHTML = '<iframe id='+reqIframeId+' name='+reqIframeId+'></iframe>';
requestDiv.style.display = 'none';
document.body.appendChild(requestDiv);
}
requestForm = document.getElementById(reqFromId);
if(requestForm){
document.body.removeChild(requestForm);
}
requestForm = document.createElement("form");
requestForm.id = reqFromId;
requestForm.method = 'POST';
requestForm.action = sUrl;
requestForm.target = reqIframeId ;
requestForm.style.display = 'none';
document.body.appendChild(requestForm);
};
/**
* init form childs
* @param data
* @param parent
*/
function initFormElements(data, parent){
for(var c in data){
if (data.hasOwnProperty(c)){
if(isArray(data[c])){
initFormElements(data[c][0], c);
}else if(isObject(data[c])){
initFormElements(data[c], c);
}else{
if(parent){
var seq = document.createElement("input");
seq.type = 'hidden';
seq.name = parent +'.'+ c ;
seq.value = data[c];
requestForm.appendChild(seq);
}else{
var seq = document.createElement("input");
seq.type = 'hidden';
seq.name = c ;
seq.value = data[c];
requestForm.appendChild(seq);
}
}
}
}
}
/**
* request task by form
*/
function requestTaskByForm(){
initJsonElements();
initHtmlElements();
initFormElements(oCif);
if(requestForm)requestForm.submit();
}
/**
* init iframe response innerHTML
*/
function initResponse(){
requestIframe = document.getElementById(reqIframeId);
var iframeWindow = document.getElementById(reqIframeId).contentWindow ;
if(iframeWindow
&& iframeWindow.document
&& iframeWindow.document.body
&& iframeWindow.document.body.innerHTML){
iframeWindow.document.body.innerHTML='';
}
}
/**
* stopTask
* @param intervalId
*/
function stopTask(intervalId){
clearInterval(intervalId);
initResponse();
};
/**
* startTask
* @param func
* @param start
* @param interval
* @param end
*/
function startTask(func, start, interval, end){
if (!start) start = 0;
if (arguments.length <= 2){
setTimeout(func, start);
}else{
function repeat() {
taskId = setInterval(func, interval);
if (end) setTimeout(function() {
stopTask(taskId);
}, end);
};
setTimeout(repeat, start);
}
};
/**
* translate response
*/
function translateResponse(){
var iframeWindow = document.getElementById(reqIframeId).contentWindow ;
if(iframeWindow
&& iframeWindow.document
&& iframeWindow.document.body
&& iframeWindow.document.body.innerHTML){
var res = iframeWindow.document.body.innerHTML;
if(res !=''){
var response = parseJson(res);
if(response.RTNCOD == 'SUC0000'){
initResponse();
if(requestForm)requestForm.submit();
}else{
if(scope)
fCallback.call(scope,res);
else
fCallback.call(this,res);
stopTask(taskId);
}
}
}
};
API下载
Blob 对象只有在IE10及以上支持
$http({
url: 'http://xxxx/xxxx',
method: 'post',
data: {
type: '类型',
selectedCols: '选择的列'
},
dataType: 'json',
responseType: 'arraybuffer'
}).success(function (data, status, headers, config) {
var fileName = name +'-' + new Date();
var blob = new Blob([data], {type: "application/vnd.ms-excel"});
if (window.navigator.msSaveOrOpenBlob){
navigator.msSaveBlob(blob, fileName);//IE
} else {
var link = document.createElement('a');
link.href = window.URL.createObjectURL(blob);
link.download = fileName;
link.click();
window.URL.revokeObjectURL(link.href);
}
}).then(clear()).error(function (data, status, headers, config) {
console.log('error');
});
FileSaver.js 兼容性处理
https://github.com/eligrey/Fi...
Blob 对象只有在IE10及以上支持
var FileSaver = require('file-saver');
var blob = new Blob(["Hello, world!"], {type: "text/plain;charset=utf-8"});
FileSaver.saveAs(blob, "hello world.txt");
前端将table生成EXCEL
https://github.com/rainabba/j...
$("#yourHtmTable").table2excel({
exclude: ".excludeThisClass",
name: "表格名称",
filename: "SomeFile" //do not include extension
});
5、文件上传
https://github.com/mailru/Fil...
https://github.com/transloadi...
6、防止网页被嵌入框架
try{
top.location.hostname;
if (top.location.hostname != window.location.hostname) {
top.location.href =window.location.href;
}
}catch(e){
top.location.href = window.location.href;
}
7、快速排序
http://www.ruanyifeng.com/blo...
8、cookie设置及获取
//写cookies(设置作用域)
function setCookie(name,value,days){
var Days = 30;
var exp = new Date();
exp.setTime(exp.getTime() + days*24*60*60*1000);
let hostname = location.hostname.substring(location.hostname.indexOf(".")+1) //设置为一级域名
document.cookie = name + "="+ escape (value) + ";expires=" + exp.toGMTString()+";domain="+hostname+";path=/";
}
//读取cookies
function getCookie(name)
{
var arr,reg=new RegExp("(^| )"+name+"=([^;]*)(;|$)");
if(arr=document.cookie.match(reg))
return (arr[2]);
else
return null;
}
//删除cookies
function delCookie(name){
setCookie(name, '', -1)
}
9、获取URL参数
// 获取参数值
function getQueryString(name) {
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
var r = window.location.search.substr(1).match(reg);
if (r != null) return unescape(r[2]);
return null;
}
// 获取url中的参数并以对象的形式展示出来
function getUrlData(){
let url=window.location.search;//url中?之后的部分
console.log('url....'+url)
url=url.substring(1);//去掉?剩下的都为a=b&c=d&e=f...模式
console.log('去掉?....'+url)
let dataObj={};
if(url.indexOf('&')>-1){
url=url.split('&');//url中去掉&全部变成“a=b” “c=d” “e=f”的模式
console.log('去掉&的url...'+url)
for(let i=0;i<url.length;i++){
let arr=url[i].split("=");
console.log("以=分割的代码...."+arr)
dataObj[arr[0]]=arr[1];
console.log("dataObj..."+dataObj);
}
}else{
url=url.split("=");
dataObj[url[0]]=url[1];
}
return dataObj;
}
10、判断是否为对象
// isObjectEqual
export function isObjectValueEqual (a, b) {
let o1 = a instanceof Object;
let o2 = b instanceof Object;
if (!o1 || !o2) {
return a === b;
}
let aProps = Object.getOwnPropertyNames(a);
let bProps = Object.getOwnPropertyNames(b);
for (let i = 0; i < aProps.length; i++) {
let t1 = aProps[i] instanceof Object;
let t2 = bProps[i] instanceof Object;
if (t1 && t2) {
return isObjectValueEqual(aProps[i], bProps[i]);
} else if (aProps[i].indexOf('_') !== 0 && a[aProps[i]] !== b[aProps[i]]) {
return false;
}
}
return true;
}
11、判断IE浏览器版本
export function IEVersion () {
let userAgent = navigator.userAgent; // 取得浏览器的userAgent字符串
let isIE = userAgent.indexOf('compatible') > -1 && userAgent.indexOf('MSIE') > -1; // 判断是否IE<11浏览器
let isEdge = userAgent.indexOf('Edge') > -1 && !isIE; // 判断是否IE的Edge浏览器
let isIE11 = userAgent.indexOf('Trident') > -1 && userAgent.indexOf('rv:11.0') > -1;
if (isIE) {
let reIE = new RegExp('MSIE (\\d+\\.\\d+);');
reIE.test(userAgent);
let fIEVersion = parseFloat(RegExp['$1']);
if (fIEVersion === 7) {
return 7;
} else if (fIEVersion === 8) {
return 8;
} else if (fIEVersion === 9) {
return 9;
} else if (fIEVersion === 10) {
return 10;
} else {
return 6; // IE版本<=7
}
} else if (isEdge) {
return 'edge'; // edge
} else if (isIE11) {
return 11; // IE11
} else {
return -1; // 不是ie浏览器
}
}
12、事件延时
export function debounce (func, delay) {
let timer;
return function (...args) {
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
func.apply(this, args);
}, delay);
};
}
13、获取元素到相对坐标
/**
* 获取元素到相对元素或者文档区域的坐标
* @param {需要计算的dom元素} element
* @param {相对元素,默认为文档} parent
*/
export function getPosition(element, parent) {
let actualLeft = element.offsetLeft,
actualTop = element.offsetTop,
current = element.offsetParent; // 取得元素的offsetParent
// 一直循环直到根元素
while (current) {
actualLeft += current.offsetLeft;
actualTop += current.offsetTop;
current = current.offsetParent;
}
if (parent) {
actualLeft = actualLeft - parent.getBoundingClientRect().left
actualTop = actualTop - parent.getBoundingClientRect().top
}
return {
left: actualLeft,
top: actualTop
}
}
14、获取隐藏元素的实际宽度、高度
/**
* 获取隐藏元素的实际宽度、高度
* @param {*} elem
*/
export function getElementSize(elem){
var width,
height,
noneNodes = [],
nodeStyle = [];
getNoneNode(elem); //获取多层display:none;的元素
setNodeStyle();
width = elem.clientWidth;
height = elem.clientHeight;
resumeNodeStyle();
return {
width : width,
height : height
}
function getNoneNode(node){
var display = getStyles(node).getPropertyValue('display'),
tagName = node.nodeName.toLowerCase();
if(display != 'none' && tagName != 'body'){
getNoneNode(node.parentNode);
} else {
noneNodes.push(node);
if(tagName != 'body')
getNoneNode(node.parentNode);
}
}
//这方法才能获取最终是否有display属性设置,不能style.display。
function getStyles(elem) {
var view = elem.ownerDocument.defaultView;
if (!view || !view.opener) {
view = window;
}
return view.getComputedStyle(elem);
};
function setNodeStyle(){
var i = 0;
for(; i < noneNodes.length; i++){
var visibility = noneNodes[i].style.visibility,
display = noneNodes[i].style.display,
style = noneNodes[i].getAttribute("style");
//覆盖其他display样式
noneNodes[i].setAttribute("style", "visibility:hidden;display:block !important;" + style);
nodeStyle[i] = {
visibility :visibility,
display : display
}
}
}
function resumeNodeStyle(){
var i = 0;
for(; i < noneNodes.length; i++){
noneNodes[i].style.visibility = nodeStyle[i].visibility;
noneNodes[i].style.display = nodeStyle[i].display;
}
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。