工作多年积攒的常用JavaScript工具函数

Posted heath_learning

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了工作多年积攒的常用JavaScript工具函数相关的知识,希望对你有一定的参考价值。

1、普通常用工具函数

1.获取变量的数据类型(jQuery源码)

function getType (obj) {
    var class2type = {};
    if (obj == null) {
        return obj + "";
    }
    return typeof obj === "object" || typeof obj === "function" ?
        class2type[toString.call(obj)] || "object" :
        typeof obj;
}

2.对象转 query string 参数(jQuery代码)

function objectToQueryString(a, traditional) {
    var getType = function (obj) {
        var class2type = {};
        if (obj == null) {
            return obj + "";
        }
        return typeof obj === "object" || typeof obj === "function" ?
            class2type[toString.call(obj)] || "object" :
            typeof obj;
    }
    var isPlainObject = function (obj) {
        var proto, Ctor;
        // Detect obvious negatives
        // Use toString instead of jQuery.type to catch host objects
        if (!obj || toString.call(obj) !== "[object Object]") {
            return false;
        }
        proto = Object.getPrototypeOf(obj);
        // Objects with no prototype (e.g., `Object.create( null )`) are plain
        if (!proto) {
            return true;
        }
        // Objects with prototype are plain iff they were constructed by a global Object function
        Ctor = ({}).hasOwnProperty.call(proto, "constructor") && proto.constructor;
        return typeof Ctor === "function" && ({}).toString.call(Ctor) === ({}).toString.call(Object);
    };
    var rbracket = /\\[\\]$/;
    var isFunction = function isFunction(obj) {
        return typeof obj === "function" && typeof obj.nodeType !== "number";
    };
    var isWindow = function isWindow(obj) {
        return obj != null && obj === obj.window;
    };
    var isArrayLike = function (obj) {
        var length = !!obj && "length" in obj && obj.length,
            type = getType(obj);
        if (isFunction(obj) || isWindow(obj)) {
            return false;
        }
        return type === "array" || length === 0 ||
            typeof length === "number" && length > 0 && (length - 1) in obj;
    }
    var each = function (obj, callback) {
        var length, i = 0;
        if (isArrayLike(obj)) {
            length = obj.length;
            for (; i < length; i++) {
                if (callback.call(obj[i], i, obj[i]) === false) {
                    break;
                }
            }
        } else {
            for (i in obj) {
                if (callback.call(obj[i], i, obj[i]) === false) {
                    break;
                }
            }
        }
        return obj;
    }
    var buildParams = function (prefix, obj, traditional, add) {
        var name;
        if (Array.isArray(obj)) {
            // Serialize array item.
            each(obj, function (i, v) {
                if (traditional || rbracket.test(prefix)) {
                    // Treat each array item as a scalar.
                    add(prefix, v);
                } else {
                    // Item is non-scalar (array or object), encode its numeric index.
                    buildParams(
                        prefix + "[" + (typeof v === "object" && v != null ? i : "") + "]",
                        v,
                        traditional,
                        add
                    );
                }
            });
        } else if (!traditional && getType(obj) === "object") {
            // Serialize object item.
            for (name in obj) {
                buildParams(prefix + "[" + name + "]", obj[name], traditional, add);
            }
        } else {
            // Serialize scalar item.
            add(prefix, obj);
        }
    }
    var prefix,
        s = [],
        add = function (key, valueOrFunction) {
            // If value is a function, invoke it and use its return value
            var value = typeof valueOrFunction == \'function\' ?
                valueOrFunction() :
                valueOrFunction;
            s[s.length] = encodeURIComponent(key) + "=" +
                encodeURIComponent(value == null ? "" : value);
        };
    if (a == null) {
        return "";
    }

    // If an array was passed in, assume that it is an array of form elements.
    if (Array.isArray(a) || (a.jquery && !isPlainObject(a))) {
        // Serialize the form elements
        each(a, function () {
            add(this.name, this.value);
        });
    } else {
        // If traditional, encode the "old" way (the way 1.3.2 or older
        // did it), otherwise encode params recursively.
        for (prefix in a) {
            buildParams(prefix, a[prefix], traditional, add);
        }
    }
    // Return the resulting serialization
    return s.join("&");
}

3.获取url参数(jQuery代码)

function getUrlParams(queryString) {
    if (!queryString) {
        return;
    }
    if (queryString.search(/\\?/) > -1) {
        queryString = queryString.split(\'?\')[1];
    }else{
        return {};
    }
    // var queryStringArr = decodeURIComponent(queryString).split(\'&\');
    var queryStringArr = queryString.split(\'&\');
    var res = {};
    var reg = /\\[\\]$/;
    queryStringArr.forEach(function (item) {
        var itemArr = item.split(\'=\');
        var name = decodeURIComponent(itemArr[0]);
        var value = decodeURIComponent(itemArr[1]);
        // 如果是数字则将其转换成number类型
        if (/^\\d+$/.test(value) && (value.length < 11)) {
            value = value * 1;
        }
        // 判断是否是多选的
        if (reg.test(name)) {
            name = name.replace(/\\[\\]/, \'\');
            if (res[name]) {
                res[name].push(value);
            } else {
                res[name] = [value];
            }
        } else {
            res[name] = value;
        }
    });
    return res;
}

4.清除字符串两端空格,包含换行符、制表符

function trim (str) {
    if (str.length === 0) {
      return str;
    }
    str += \'\';
    // 清除字符串两端空格,包含换行符、制表符
    return str.replace(/(^[\\s\\n\\t]+|[\\s\\n\\t]+$)/g, \'\');
}

5.将科学计数法的值转换成正常数字

 function toNonExponential (num) {
    var m = num.toExponential().match(/\\d(?:\\.(\\d*))?e([+-]\\d+)/);
    return num.toFixed(Math.max(0, (m[1] || \'\').length - m[2]));
  }

6.根据指定url获取url的域名

function getBaseUrl (_url) {
    if(!_url){ return \'\'; }
    let aEle = document.createElement(\'a\');
    let url = \'\';
    aEle.href = _url;
    url += aEle.protocol + \'//\' + aEle.host;
    aEle = null;
    return url;
}

7.获取url的基本信息

function getUrlInfo(_url){
    let aEle = document.createElement(\'a\');
    aEle.href = _url || location.href;
    let obj = {
      protocol: aEle.protocol,
      host: aEle.host,
      pathname: aEle.pathname,
      search: aEle.search,
      hash: aEle.hash
    };
    return obj;
}

8.获取元素在数组中的下标

/**
   * 获取数组中符合条件的元素的索引
   * @param arr 数组
   * @param fn 一个函数,如果函数返回true,则返回该项的下标,如果没有找到则返回-1
   *  */
 function getIndex (arr, fn) {
    if (!arr || arr.length === 0 || !fn || (typeof fn !== \'function\')) {
      return -1;
    }

    if (arr.findIndex) {
      return arr.findIndex(fn);
    }
    let len = arr.length;
    let i = 0;
    let index = -1;
    for (; i < len; i++) {
      let item = arr[i];
      if (fn(item, index, arr) === true) {
        index = i;
        break;
      }
    }
    return index;
}

9.获取浏览器使用的语言

function getBrowserLang () {
    var type = navigator.appName;
    let lang = \'\';
    if (type === \'Netscape\') {
      // 获取浏览器配置语言,支持非IE浏览器
      lang = navigator.language;
    } else {
      // 获取浏览器配置语言,支持IE5+ == navigator.systemLanguage
      lang = navigator.userLanguage;
    }
    return lang.toLowerCase();
}

10.给数字前面补零

/**
   * 给数字前面补零
   * 如:padStartZero(10) => 10
   *    padStartZero(5) => 05
   * @param num
   * @returns {string}
   */
 function padStartZero (num) {
    return (\'00\' + num).substr((num + \'\').length);
 }

11.截取数字整数位长度(从低位往高位截)

/**
   * 如:limitInt(12, 3) => 12
   *    limitInt(145678, 3) => 145
   *    limitInt(1456.78, 3) => 145.78
   * @param num
   * @param maxSize
   * @returns {string}
   */
function limitInt(num, maxSize) {
    num = num + "";
    let numArr = num.split(".");
    let len = (numArr[0] + "").length;
    if (len > maxSize) {
      numArr[0] = numArr[0].substring(0, maxSize);
    } else {
      return num;
    }
    return numArr.join(".");
}

12.截取数字小数位长度

/**
   * 如:limeDecimal(12, 3) => 12
   *    limeDecimal(14.5678, 3) => 14.557
   *    limeDecimal(1456.78, 3) => 1456.78
   * @param num
   * @param maxSize
   * @returns {string}
   */
function limitDecimal(num, maxSize) {
    if (typeof maxSize == "undefined") {
      return num;
    }
    num = num + "";

    let numArr = num.split(".");
    if (numArr.length == 1) {
      return num;
    }
    if ((numArr[1] + "").length > maxSize) {
      numArr[1] = numArr[1].substr(0, maxSize);
    } else {
      return num;
    }
    return numArr.join(".");
}

13.将数字格式化到指定位数的小数

/**
   * 如:decimalPadZero(10,2) => 10.00
   *     decimalPadZero(10.5,2) => 10.50
   *     decimalPadZero(10.5678,2) => 10.56
   * @param number 数字
   * @param scall 保留小数后多少位
   * @returns {string}
   */
function decimalRetain(number, scale) {
    if (isNaN(Number(number))) {
      return number;
    }
    let result = [\'\', \'\'];
    let num = number.toString();
    if (num.indexOf(\'.\') !== -1) {
      let arr = num.split(\'.\');
      result[0] = arr[0];
      if (arr[1].length === scale) {
        result[0] += \'.\' + arr[1];
      } else if (arr[1].length > scale) {
        result[1] = \'.\';
        result[1] += arr[1].substring(0, scale - 1);
      } else if (arr[1].length < scale) {
        let zeros = (scale + 1) - arr[1].length;
        result[0] += \'.\' + arr[1];
        result[1] = Array(zeros).join(0);
      }
    } else {
      result[0] = num;
      result[1] = \'.\' + (Array(scale + 1).join(0));
    }
    return result.join("").replace(/\\.+$/, "");
}

14.数字前面补零

/**
   * 如:padStartZero(10) => 10
   *    padStartZero(5) => 05
   * @param num
   * @returns {string}
   */
function padStartZero (num) {
    return (\'00\' + num).substr((num + \'\').length);
}

15.判断对象是否是一个空对象

/**
   * 判断对象是否是一个空对象
   * @param obj
   */
function isEmptyObject (obj) {
    for (var attr in obj) {
      return false;
    }
    return true;
}

16.下载文件

/**
 * 下载文件
 * @param fileData 文件数据
 * @param fileName 文件名称
 * @param mimeType 文件类型
 * @param notSupportCallback 浏览器不支持下载时的回调
 */
function downloadFile (fileData, fileName, mimeType, notSupportCallback) {
    if (!window.Blob) {
        notSupportCallback();
        return;
    }
    // console.log(\'数据类型:\', typeof fileData);
    if (!(fileData instanceof Blob)) {
        // 默认为文本文件
        let type = typeof mimeType === \'string\' ? mimeType : \'text/plain\'; 
        fileData = new Blob([fileData], { type });
    }
    let eleA = document.createElement(\'a\');
    if (\'download\' in eleA) { // 非IE下载
        let url = URL.createObjectURL(fileData);
        eleA.href = url;
        eleA.download = fileName;
        eleA.style.display = \'none\';
        document.body.append(eleA);
        let timer = setTimeout(() => {
            clearTimeout(timer);
            eleA.click();
            URL.revokeObjectURL(url);
            document.body.removeChild(eleA);
            eleA = null;
            url = null;
        }, 0);
    } else if (navigator.msSaveBlob) { // IE10下载
        navigator.msSaveBlob(fileData, fileName);
    }
}

17.下载网络图片

(function (root, factory) {
    if (typeof define === \'function\' && define.amd) {
        // AMD. Register as an anonymous module.
        define([], factory);
    } else if (typeof exports === \'object\') {
        // Node. Does not work with strict CommonJS, but
        // only CommonJS-like environments that support module.exports,
        // like Node.
        module.exports = factory();
    } else {
        // Browser globals (root is window)
        root.download = factory();
  }
}(this, function () {

    return function download(data, strFileName, strMimeType) {

        var self = window, // this script is only for browsers anyway...
            defaultMime = "application/octet-stream", // this default mime also triggers iframe downloads
            mimeType = strMimeType || defaultMime,
            payload = data,
            url = !strFileName && !strMimeType && payload,
            anchor = document.createElement("a"),
            toString = function(a){return String(a);},
            myBlob = (self.Blob || self.MozBlob || self.WebKitBlob || toString),
            fileName = strFileName || "download",
            blob,
            reader;
            myBlob= myBlob.call ? myBlob.bind(self) : Blob ;
      
        if(String(this)==="true"){ //reverse arguments, allowing download.bind(true, "text/xml", "export.xml") to act as a callback
            payload=[payload, mimeType];
            mimeType=payload[0];
            payload=payload[1];
        }


        if(url && url.length< 2048){ // if no filename and no mime, assume a url was passed as the only argument
            fileName = url.split("/").pop().split("?")[0];
            anchor.href = url; // assign href prop to temp anchor
              if(anchor.href.indexOf(url) !== -1){ // if the browser determines that it\'s a potentially valid url path:
                var ajax=new XMLHttpRequest();
                ajax.open( "GET", url, true);
                ajax.responseType = \'blob\';
                ajax.onload= function(e){ 
                  download(e.target.response, fileName, defaultMime);
                };
                setTimeout(function(){ ajax.send();}, 0); // allows setting custom ajax headers using the return:
                return ajax;
            } // end if valid url?
        } // end if url?


        //go ahead and download dataURLs right away
        if(/^data\\:[\\w+\\-]+\\/[\\w+\\-]+[,;]/.test(payload)){
        
            if(payload.length > (1024*1024*1.999) && myBlob !== toString ){
                payload=dataUrlToBlob(payload);
                mimeType=payload.type || defaultMime;
            }else{            
                return navigator.msSaveBlob ?  // IE10 can\'t do a[download], only Blobs:
                    navigator.msSaveBlob(dataUrlToBlob(payload), fileName) :
                    saver(payload) ; // everyone else can save dataURLs un-processed
            }
            
        }//end if dataURL passed?

        blob = payload instanceof myBlob ?
            payload :
            new myBlob([payload], {type: mimeType}) ;


        function dataUrlToBlob(strUrl) {
            var parts= strUrl.split(/[:;,]/),
            type= parts[1],
            decoder= parts[2] == "base64" ? atob : decodeURIComponent,
            binData= decoder( parts.pop() ),
            mx= binData.length,
            i= 0,
            uiArr= new Uint8Array(mx);

            for(i;i<mx;++i) uiArr[i]= binData.charCodeAt(i);

            return new myBlob([uiArr], {type: type});
         }

        function saver(url, winMode){

            if (\'download\' in anchor) { //html5 A[download]
                anchor.href = url;
                anchor.setAttribute("download", fileName);
                anchor.className = "download-js-link";
                anchor.innerHTML = "downloading...";
                anchor.style.display = "none";
                document.body.appendChild(anchor);
                setTimeout(function() {
                    anchor.click();
                    document.body.removeChild(anchor);
                    if(winMode===true){setTimeout(function(){ self.URL.revokeObjectURL(anchor.href);}, 250 );}
                }, 66);
                return true;
            }

            // handle non-a[download] safari as best we can:
            if(/(Version)\\/(\\d+)\\.(\\d+)(?:\\.(\\d+))?.*Safari\\//.test(navigator.userAgent)) {
                url=url.replace(/^data:([\\w\\/\\-\\+]+)/, defaultMime);
                if(!window.open(url)){ // popup blocked, offer direct download:
                    if(confirm("Displaying New Document\\n\\nUse Save As... to download, then click back to return to this page.")){ location.href=url; }
                }
                return true;
            }

            //do iframe dataURL download (old ch+FF):
            var f = document.createElement("iframe");
            document.body.appendChild(f);

            if(!winMode){ // force a mime that will download:
                url="data:"+url.replace(/^data:([\\w\\/\\-\\+]+)/, defaultMime);
            }
            f.src=url;
            setTimeout(function(){ document.body.removeChild(f); }, 333);

        }//end saver




        if (navigator.msSaveBlob) { // IE10+ : (has Blob, but not a[download] or URL)
            return navigator.msSaveBlob(blob, fileName);
        }

        if(self.URL){ // simple fast and modern way using Blob and URL:
            saver(self.URL.createObjectURL(blob), true);
        }else{
            // handle non-Blob()+non-URL browsers:
            if(typeof blob === "string" || blob.constructor===toString ){
                try{
                    return saver( "data:" +  mimeType   + ";base64,"  +  self.btoa(blob)  );
                }catch(y){
                    return saver( "data:" +  mimeType   + "," + encodeURIComponent(blob)  );
                }
            }

            // Blob but not URL support:
            reader=new FileReader();
            reader.onload=function(e){
                saver(this.result);
            };
            reader.readAsDataURL(blob);
        }
        return true;
    }; /* end download() */
}));

// 下载一张图片
function downloadImg(url, imgName, fn){
    var x=new XMLHttpRequest();
    var name = imgName ? (imgName + \'.png\') : (new Date().getTime() + \'.png\');
    x.open("GET", url, true);
    x.responseType = \'blob\';
    x.onload = function (e) {
        download(x.response, name, "image/png" );
        console.log(\'图片下载完成\');
        if(typeof fn === \'function\'){
            fn();
        }
    }
    x.send();
}

// 批量下载
function downloadImgBatch(imgArr){
    let timer = setInterval(function () {
        console.log(\'imgArr.length\', imgArr.length);
        if(imgArr.length > 0){
            let img = imgArr.shift(0);
            downloadImg(img.url, img.name);
        }else{
            clearInterval(timer);
        }
    }, 500);
}

18.格式化日期

/**
   * 格式化日期
   * 如:
   *  formatDate(new Date) => 2018-07-27 14:32:25
   *  formatDate(1532673162672) => 2018-07-27 14:32:25
   *  formatDate("abc1532673162672def") => 2018-07-27 14:32:25
   *  formatDate(new Date, "yyyy年MM月dd日 hh时mm分ss秒") => 2018年07月27日 14时32分25秒
   * @param dateTemp
   * @param format
   * @returns {string}
   */
  function formatDate (dateTemp, format = \'yyyy-MM-dd hh:mm:ss\') {
    if(typeof dateTemp === \'undefined\' || dateTemp === null){
      console.error(\'dateTemp不是一个合法的值,dateTemp可以为:时间戳、日期时间字符串、Date对象\');
      return;
    }
    if (typeof dateTemp === \'object\' && !(/Date/.test(({}).toString.call(dateTemp)))) {
      console.error(\'dateTemp不是一个Date对象,请检查dateTemp数据类型!\');
      return;
    }
    let date;
    if (typeof dateTemp !== \'object\') {
      let dateStr = dateTemp + \'\';
      dateStr = /\\d{13,}/.exec(dateStr);
      if (!dateStr) {
        // console.error(dateTemp + \' 不是一个合法的时间戳!\');
        date = new Date(dateTemp.replace(/\\-/g, \'/\'));
        // return;
      }else{
        date = new Date(dateStr * 1);
      }
    } else {
      date = dateTemp;
    }
    if (/(y{0,4})/.test(format)) {
      format = format.replace(/y{0,4}/, (date.getFullYear() + \'\').substr(4 - RegExp.$1.length));
    }
    let obj = {
      \'M+\': (date.getMonth() + 1 + \'\'),
      \'d+\': (date.getDate() + \'\'),
      \'h+\': (date.getHours() + \'\'),
      \'m+\': (date.getMinutes() + \'\'),
      \'s+\': (date.getSeconds() + \'\'),
    };
    for (let attr in obj) {
      if (new RegExp(\'(\' + attr + \')\').test(format)) {
        format = format.replace(new RegExp(attr), tool.padStartZero(obj[attr]).substr(2 - RegExp.$1.length));
      }
    }
    return format;
  }

2.DOM常用工具函数

1.绑定事件

/**
   * 绑定事件
   * @param ele dom元素
   * @param eventName 事件名称
   * @param fn 事件回调函数
   */
 function bindEvent (ele, eventName, fn) {
    if (!ele) {
      console.error(\'on(ele, eventName, fn)函数第一个参数必须是一个dom元素!\');
      return;
    }
    if (!eventName || typeof eventName !== \'string\') {
      console.error(\'on(ele, eventName, fn)函数第二个参数必须是一个字符串!\');
      return;
    }
    if (!fn || typeof fn !== \'function\') {
      console.error(\'on(ele, eventName, fn)函数第三个参数必须是一个函数!\');
      return;
    }
    if (!ele._events) {
      ele._events = {};
    }

    if (!(eventName in ele._events)) {
      ele._events[eventName] = [fn];
      if (document.addEventListener) {
        var eventFn = function (e) {
          var events = ele._events[eventName];
          if (events && events.length > 0) {
            for (var i = 0, len = events.length; i < len; i++) {
              if (events[i]) {
                events[i].call(ele, e);
              }
            }
          }
        };
        ele.addEventListener(eventName, eventFn, false);
        // 把事件回调函数也存起来,这样在移除事件的时候才能真正的把该事件移除掉
        ele._events[eventName + \'_fn\'] = eventFn;
      } else if (window.attachEvent) {
        var eventFn = function () {
          var events = ele._events[eventName];
          var e = window.event;
          e.preventDefault = function () {
            e.returnValue = false;
          };
          e.stopPropagation = function () {
            e.cancelBubble = true;
          };
          for (var i = 0, len = events.length; i < len; i++) {
            events[i].call(ele, e);
          }
        };
        ele.attachEvent(\'on\' + eventName, eventFn);
        ele._events[eventName + \'_fn\'] = eventFn;
      }
    } else {
      //ele._events[eventName] = [fn];
      var index = this.getIndex(ele._events[eventName], function (item) {
        return item === fn;
      });
      if (index < 0 || typeof index === \'undefined\') {
        ele._events[eventName].push(fn);
      }
    }
}

2.解绑事件

/**
   * 解绑事件
   * @param ele dom元素
   * @param eventName 事件名称
   * @param fn 事件回调函数
   */
function unBindEvent (ele, eventName, fn) {
    if (!ele) {
      console.error(\'off(ele, eventName, fn)函数第一个参数必须是一个dom元素!\');
      return;
    }
    if (!eventName || typeof eventName !== \'string\') {
      console.error(\'off(ele, eventName, fn)函数第二个参数必须是一个字符串!\');
      return;
    }
    if (!ele._events) {
      return;
    }
    if (!eventName) {
      return;
    }
    console.log(\'off\', eventName, ele);
    var events = ele._events[eventName];
    var eventFn = ele._events[eventName + \'_fn\'];
    // 如果只传递了事件名称而未传递具体的事件,则将指定事件名称的所有回调函数全部清除
    if (eventName && !fn) {
      if (document.removeEventListener) {
        //for(var i = 0, len = events.length; i < len; i++){
        ele.removeEventListener(eventName, eventFn, false);
        //}
      } else if (window.detachEvent) {
        //for(var i = 0, len = events.length; i < len; i++){
        ele.detachEvent(\'on\' + eventName, eventFn);
        //}
      }
      delete ele._events[eventName];
      delete ele._events[eventName + \'_fn\'];
    } else if (eventName && fn) {
      if (!events) {
        return;
      }
      if (document.removeEventListener) {
        var index = this.getIndex(events, function (item) {
          return item === fn;
        });
        if (index > -1) {
          events.splice(index, 1);
        }
        if (events.length === 0) {
          delete ele._events[eventName];
          delete ele._events[eventName + \'_fn\'];
        }
      } else if (window.detachEvent) {
        if (!events) {
          return;
        }
        var index = this.getIndex(events, function (item) {
          return item === fn;
        });
        if (index > -1) {
          events.splice(index, 1);
        }
        if (events.length === 0) {
          delete ele._events[eventName];
          delete ele._events[eventName + \'_fn\'];
        }
      }
    }
    events = null;
}

3.给指定元素添加class

/**
   * @param ele
   * @param classname
   */
function addClass (ele, classname) {
    if (!ele || !classname || ele.nodeType !== 1) {
      return;
    }
    let classArr = classname.split(\' \');
    if (ele.classList) {
      for (var i = 0, len = classArr.length; i < len; i++) {
        let item = classArr[i];
        if (!ele.classList.contains(item)) {
          ele.classList.add(item);
        }
      }
      return ele;
    } else {
      let classNameArr = ele.className && ele.className.length > 0 ? ele.className.split(\' \') : [];
      if (classNameArr.length === 0) {
        ele.className = classname;
        return;
      }
      // 合并两个数组
      Array.prototype.push.apply(classNameArr, classArr);
      classNameArr = tool.arrayNoReapeat(classNameArr);
      ele.className = classNameArr.join(\' \');
      return ele;
    }
}

4.给指定元素移除class

/**
   * @param ele
   * @param classname
   */
function removeClass (ele, classname) {
    if (!ele || !classname || ele.nodeType !== 1) {
      return;
    }
    let classArr = classname.split(\' \');
    if (ele.classList) {
      for (var i = 0, len = classArr.length; i < len; i++) {
        let item = classArr[i];
        if (ele.classList.contains(item)) {
          ele.classList.remove(item);
        }
      }
      return ele;
    } else {
      let classNameArr = ele.className && ele.className.length > 0 ? ele.className.split(\' \') : [];
      if (classNameArr.length === 0) {
        return;
      }
      for (var i = classNameArr.length; i >= 0; i--) {
        for (var j = 0, len2 = classArr.length; j < len2; j++) {
          if (classNameArr[i] === classArr[j]) {
            classNameArr.splice(i, 1);
          }
        }
      }
      ele.className = classNameArr.join(\' \');
      return ele;
    }
}

5.判断元素是否包含指定className

/**
   * 判断元素是否包含指定className
   * @param ele dom元素
   * @param className className
   * @returns {boolean}
   */
function hasClass (ele, className) {
    if (!ele || !ele.nodeName) {
      console.error(\'ele 必须是一个dom元素\');
      return;
    }
    if (!className) {
      console.error(\'className 必须是一个字符串\');
      return;
    }
    if (ele.classList) {
      return ele.classList.contains(className);
    } else {
      let flag = false;
      let classNameArr = ele.className.split(\' \');
      for (let i = 0, len = classNameArr.length; i < len; i++) {
        if (classNameArr[i] === className) {
          flag = true;
          break;
        }
      }
      return flag;
    }
}

6.获取元素的css属性值

/**
   * 获取元素的css属性值
   * @param ele dom元素
   * @param cssAttribute css属性名称
   */
function getStyle (ele, cssAttribute) {
    if (!ele || !ele.nodeName) {
      console.error(\'ele 必须是一个dom元素\');
      return;
    }
    if (!cssAttribute) {
      console.error(\'cssAttribute 必须是一个字符串\');
      return;
    }
    let val = \'\';
    if (window.getComputedStyle) {
      val = window.getComputedStyle(ele, null)[cssAttribute];
    } else if (ele.currentStyle) {
      val = ele.currentStyle[cssAttribute];
    }
    if (!isNaN(parseFloat(val))) {
      return parseFloat(val);
    } else {
      return val;
    }
}

7.给元素设置css属性

/**
   * 给元素设置css属性
   * @param ele dom元素
   * @param attr css属性名
   * @param val css属性值,如果不传递attr参数,则该参数可以为一个对象,就像jquery的css()方法一样
   */
function setCss (ele, attrs, val) {
    if (!ele || !ele.nodeName) {
      console.error(\'ele 必须是一个dom元素\');
      return;
    }
    let type1 = ({}).toString.call(attrs);
    // 需要字段加单位的css属性
    let autoAddUnitAttr = {
      width: 1, height: 1, margin: 1, padding: 1,
      borderRadius: 1, top: 1, left: 1,
      marginLeft: 1, marginRight: 1, marginTop: 1, marginBottom: 1,
      right: 1, bottom: 1,
      paddingLeft: 1, paddingRight: 1, paddingTop: 1, paddingBottom: 1,
      borderTopLeftRadius: 1, borderTopRightRadius: 1,
      borderBottomLeftRadius: 1, borderBottomRightRadius: 1,
      fontSize: 1, lineHeight: 1, textIndent: 1,
      minWidth: 1, maxWith: 1
    };
    if (type1 === \'[object String]\' && typeof val !== \'undefined\') {
      attrs = attrs.replace(/\\-(\\w)/g, function (matched, $1) {
        return $1.toUpperCase();
      });
      if (attrs in autoAddUnitAttr && !isNaN(Number(val))) {
        ele.style[attrs] = val + \'px\';
      } else {
        ele.style[attrs] = val;
      }
    } else if (type1 === \'[object Object]\') {
      let style = ele.style;
      for (let attr in attrs) {
        let val2 = attrs[attr];
        let isNumber = Number(val2);

        attr = attr.replace(/\\-(\\w)/g, function (matched, $1) {
          return $1.toUpperCase();
        });

        if (attr in autoAddUnitAttr && !isNaN(isNumber)) {
          style[attr] = val2 + \'px\';
        } else {
          style[attr] = val2;
        }
      }
    }
}

8.获取兄弟节点

/**
   * 获取兄弟节点
   * @param elm
   * @returns {Array}
   */
function siblings (elm) {
    let a = [];
    let p = elm.parentNode.children;
    for (let i = 0, pl = p.length; i < pl; i++) {
      if (p[i] !== elm) a.push(p[i]);
    }
    return a;
}

9.判断两个元素是否是包含关系

/**
   * 判断两个元素是否是包含关系
   * @param ele 父元素
   * @param childEle 子元素
   * @returns {Boolean}
   */
function elementContains (ele, childEle) {
    if (ele === childEle) {
      return false;
    }
    if (typeof ele.contains === \'function\') {
      return ele.contains(childEle);
    } else {
      while (true) {
        if (!childEle) {
          return false;
        }
        if (childEle === ele) {
          return true;
        } else {
          childEle = childEle.parentNode;
        }
      }
      return false;
    }
}

10.将滚动条滚动到指定元素所在位置

/**
   * 将滚动条滚动到指定元素所在位置
   * @param ele dom元素
   * @param extraTop 额外的高度,比如在元素的位置基础上加10px,或减10px
   * @param autofocus 如果是表单元素的话是否滚动完后自动获得焦点
   */
function scrollToElement (ele, extraTop, autofocus) {
    if (!ele || !ele.nodeName) {
      console.error(\'ele 必须是一个dom元素\');
      return;
    }
    autofocus = !!autofocus;
    let top = ele.offsetTop;
    let offsetParent = ele.offsetParent;

    while (offsetParent != null) {
      top += offsetParent.offsetTop;
      offsetParent = offsetParent.offsetParent;
    }
    top += extraTop;
    window.scrollTo(0, top);

    if (autofocus && ele.focus) {
      ele.focus();
    }
}

11.获取元素的指定父级元素

/**
   * 获取元素的指定父级元素
   * @param el dom 元素
   * @param className 父元素的class name
   * @returns {dom、undefined}
   */
function parents (el, className) {
    if (!el || !el.nodeName || !className) {
      return;
    }
    var classNameArr = className.split(\' \');
    var parent = el.parentElement;

    while (parent) {
      var flag = true;
      for (var i = 0, len = classNameArr.length; i < len; i++) {
        if (!this.hasClass(parent, classNameArr[i])) {
          flag = false;
          break;
        }
      }
      if (flag) {
        return parent;
      } else {
        parent = parent.parentElement;
      }
    }
}

12.获取元素距浏览器最顶部及最左边的距离

/**
   * 获取元素距浏览器最顶部及最左边的距离
   * @param ele dom元素
   */
function offset (ele) {
    let positon = {
      top: 0,
      left: 0,
    };
    let offsetParent = ele.offsetParent;
    positon.top = ele.offsetTop;
    positon.left = ele.offsetLeft;
    while (offsetParent != null) {
      positon.top += offsetParent.offsetTop;
      positon.left += offsetParent.offsetLeft;
      offsetParent = offsetParent.offsetParent;
    }
    return positon;
}

13.获取浏览器滚动条的位置

function scrollTop () {
    return window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0;
}

以上是关于工作多年积攒的常用JavaScript工具函数的主要内容,如果未能解决你的问题,请参考以下文章

关于JavaScript常用的工具函数汇总

JavaScript常用的工具函数,不全面大家补充哦

javascript代码简写的几种常用方式汇总

36个工作中常用的JavaScript函数片段

Node.js 常用工具 util

Node.js 常用工具