2
在前端工作期间遇到过不少的问题,很多时候这些问题也是反复出现的,是时候将问题都记录下来,用于回顾及避免反复浪费时间在同一问题上。

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;
    }
  }
}

toutouping
190 声望12 粉丝

每天进步一点点,遇见更好的自己


« 上一篇
AngularJS 笔记
下一篇 »
CSS笔记