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 res = {};    var reg = /\[\]$/;    queryStringArr.forEach(function (item) {        var itemArr = item.split('=');        var name = itemArr[0];        var value = 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);}

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