最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 常用的js 方法

    正文概述 掘金(Csvn)   2021-04-05   645

    深拷贝

    使用JSON.parse(JSON.stringify(object))实现深拷贝局限
        1、如果object里面有时间对象,则JSON.stringify后再JSON.parse的结果,时间将只是字符串的形式。而不是时间对象;
        2、如果object里有RegExp、Error对象,则序列化的结果将只得到空对象;
        3、如果obj里有函数、undefined、symbol,则序列化的结果会把函数或 undefined丢失;
        4、如果obj里有NaN、Infinity和-Infinity,则序列化的结果会变成null
        5、JSON.stringify()只能序列化对象的可枚举的自有属性,例如 如果obj中的对象是有构造函数生成的, 则使用JSON.parse(JSON.stringify(obj))深拷贝后,会丢弃对象的constructor;
        6、如果对象中存在循环引用的情况也无法正确实现深拷贝;
    解决办法:
     1)借用 MessageChannel 实现深拷贝
     function deepClone(val) {
        return new Promise((resolve,reject) => {
            const {port1,port2} = new MessageChannel();
            port2.onmessage = e => resolve(e.data);
            port1.postMessage(val);
        })
    }
    
    2) 简单版 递归 copy
    function deepCopy(p, c) {
      var c = c || {};
      for (var i in p) {
        if (typeof p[i] === 'object') {
          c[i] = (p[i].constructor === Array) ? [] : {};
          deepCopy(p[i], c[i]);
        } else {  
                c[i] = p[i];
        }
      }
    
      return c;
    }
        3) loadash的 _.cloneDeep()
    
    

    千位格式化数字

    /**
     * 每千位格式化
     * @param {number}} num 
     */
    export const toThousands = (num) => {
      var result = '', counter = 0;
      var dot = String(num).indexOf(".");
      if (dot != -1) {
        // alert("有小数点");
        // 获取小数点后面的数字(indexOf和substring都不支持数字,所以要先转字符串才可以用)
        var dotCnt = String(num).substring(dot + 1, num.length);
    
        // 获取小数点前面的数字
        num = String(num).split('.')[0]
        num = (num || 0).toString();
        for (var i = num.length - 1; i >= 0; i--) {
          counter++;
          result = num.charAt(i) + result;
          if (!(counter % 3) && i != 0) { result = ',' + result; }
        }
        result = result + '.' + dotCnt;
        return result;
    
      } else {
        // alert("没有小数点");
        return (num || 0).toString().replace(/(\d)(?=(?:\d{3})+$)/g, '$1,');
      }
    }
    

    判断浏览器

    const browser = {
      isAndroid: function () {
        return !!navigator.userAgent.match(/Android/i)
      },
      isIOS: function () {
        return !!navigator.userAgent.match(/iPhone|iPad|iPod/i)
      },
      isMobileQQ: function () {
        var ua = navigator.userAgent
        return /(iPad|iPhone|iPod).*? (IPad)?QQ\/([\d.]+)/.test(ua) || /\bV1_AND_SQI?_([\d.]+)(.*? QQ\/([\d.]+))?/.test(ua)
      },
      isWx: function () {
        return !!navigator.userAgent.match(/micromessenger/i)
      },
      isChrome: function () {
        return !!(navigator.userAgent.match(/Chrome\/([\d.]+)/) || navigator.userAgent.match(/CriOS\/([\d.]+)/))
      },
      isUC: function () {
        return !!navigator.userAgent.match(/UCBrowser/i)
      },
      isSafari: function () {
        return !!navigator.userAgent.match(/safari/i)
      },
      isQQBrowser: function () {
        return !!navigator.userAgent.match(/MQQBrowser/i)
      },
      isWeibo: function () {
        return !!navigator.userAgent.match(/weibo/i)
      },
      iOSVersion: function () {
        var str = navigator.userAgent.toLowerCase();
        var ver = str.match(/cpu iphone os (.*?) like mac os/);
        return ver ? parseInt(ver[1]) : 0
      }
    }
    

    动态插入script 标签

    export const injectScript = src => {
      return new Promise((resolve, reject) => {
        const script = document.createElement('script')
        script.async = true
        script.src = src
        script.addEventListener('load', resolve)
        script.addEventListener('error', reject)
        document.head.appendChild(script)
      })
    }
    

    获取当前页面的滚动位置

    const getScrollPosition = (el = window) => ({
      x: el.pageXOffset !== undefined ? el.pageXOffset : el.scrollLeft,
      y: el.pageYOffset !== undefined ? el.pageYOffset : el.scrollTop
    });
    
    使用:
    getScrollPosition(); // {x: 0, y: 200}
    
    

    平滑滚动到页面的顶部

    const scrollToTop = () => {
      const c = document.documentElement.scrollTop || document.body.scrollTop;
      if (c > 0) {
        window.requestAnimationFrame(scrollToTop);
        window.scrollTo(0, c - c / 8);
      }
    }
    
    // 使用
    scrollToTop()
    
    

    点击下载多个文件

    延时函数
    const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
    使用a 标签下载
    const download = async (url) => {
        const a = document.createElement('a');
        // a.download = name;
        a.href = url;
        a.style.display = 'none';
        document.body.append(a);
        a.click();
    
        // Chrome requires the timeout
        await delay(100);
        a.remove();
    };
    
    使用iframe 下载
    setTimeout(function () {
      let frame = document.createElement("iframe");
        frame.style.display = "none"; // 防止影响页面
        frame.style.height = 0;
        frame.src = adress;
        document.body.appendChild(frame);
        setTimeout(function () {
          document.body.removeChild(frame);
        }, 3000);
    }, 100);
     
    循环调用
    
    

    注:iframe 支持性比较不如a标签

    • 解决因为手机设置字体大小导致h5页面在webview中变形的BUG

    首先,我们做了一个H5页面,在各种手机浏览器中打开都没问题。我们采用了rem单位进行布局,通过JS来动态计算网页的视窗宽度,动态设置html的font-size,一切都比较完美。

    这时候,你自信满满的将h5地址交给了APP工程师,做了一个WEBVIEW嵌套,然后就顺利交工了。

    测试组在一堆手机中测试APP,突然,在某个手机上打开,你的页面布局了乱了,字变大或者变小,总之很奇葩。

    你怎么也不会想到是手机设置字体大小造成的。

    因为默认浏览器中的内容是不受系统字体大小设置控制的,至少我遇到的几台手机都是这样的情况。但是APP不一样,APP是受那个玩意儿控制的!

    导致因素:

    1.你的页面采用了rem单位,并且是采用js动态计算html的font-size
    
    2.你的页面被加在了APP中的webview中
    
    3.这该死的手机被重设了字体大小
    

    方案一:【h5解决】

    需要在设置完字体大小之后,再去重新获取一下html的font-size,这样就可以实现当实际的值与我们设置的值不一样时,根据比例再设置一次。

    以下是我的完整代码:

    function htmlFontSize(){
        var h = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
        var w = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
        var width = w > h ? h : w;
        width = width > 720 ? 720 : width
        var fz = ~~(width*100000/36)/10000
        document.getElementsByTagName("html")[0].style.cssText = 'font-size: ' + fz +"px";
        var realfz = ~~(+window.getComputedStyle(document.getElementsByTagName("html")[0]).fontSize.replace('px','')*10000)/10000
        if (fz !== realfz) {
            document.getElementsByTagName("html")[0].style.cssText = 'font-size: ' + fz * (fz / realfz) +"px";
        }
    }
    

    方案二:【安卓android端解决】

    安卓客户端通过webview配置webview.getSettings().setTextZoom(100)就可以禁止缩放,按照百分百显示。 webview.getSettings().setTextZoom(100); WebView加上这个设置后,WebView里的字体就不会随系统字体大小设置发生变化了.

    手机号隐藏中件位数

    var tel = "13122223333";
    
    var reg = /^(\d{3})\d{4}(\d{4})$/;
    
    tel = tel.replace(reg, "$1****$2");
    

    以字节计算 截取字符串

    export const sliceStr = (str, length) => {
      var realLength = 0, charCode = -1, sliceLength = 0 
      if(str){
        for (var i = 0; i < str.length; i++) {
          charCode = str.charCodeAt(i)
          if(+realLength < +length){
            sliceLength += 1      
          }
          if (charCode >= 0 && charCode <= 128) 
            realLength += 1
          else
            realLength += 2
        }
      }
      return {realLength, str, sliceStr: str.slice(0, sliceLength)}
    }
    

    格式化数字

    export const nFormatter = (num, digits) => {
      const si = [
        { value: 1, symbol: "" },
        { value: 1E3, symbol: "K" },
        { value: 1E6, symbol: "M" },
        { value: 1E9, symbol: "G" },
        { value: 1E12, symbol: "T" },
        { value: 1E15, symbol: "P" },
        { value: 1E18, symbol: "E" }
      ];
      let i;
      for (i = si.length - 1; i > 0; i--) {
        if (num >= si[i].value) {
          break;
        }
      }
      //if(num < si[2].value ){
      //  return num
      //}
      //return (num / si[i-1].value).toFixed(digits) + si[i-1].symbol;
      return (num / si[i].value).toFixed(digits) + si[i].symbol;
    }
    

    判断函数

    function isJSON(target) {
      return typeof target == 'object' && target.constructor == Object;
    }
    
    function isArray(o) {
      return Object.prototype.toString.call(o) == '[object Array]';
    }
    
    function isObject(o){
        return Object.prototype.toString.call(o) == '[object Object]'
    }
    
    function isString(s){
        return Object.prototype.toString.call(s) == '[object String]'
    }
    

    树相关函数

    // 获取树的广度
    function handleGetTreeExtent(node) {
        let extend = 0;
        node.forEach((item) => {
          if (item.children) {
            extend += handleGetTreeExtent(item.children);
          } else {
            extend += 1;
          }
        });
        return extend;
      }
     
    // 获取树的深度
    function handleGetTreeDeep(fileHeader) {
        let deep = 0;
        fileHeader.forEach((item) => {
          if (item.children) {
            deep = Math.max(deep, handleGetTreeDeep(item.children) + 1);
          } else {
            deep = Math.max(deep, 1);  
          }
        });
        return deep;
      }
    

    合并两个JSON对象

    var objC = {}.constructor;
    function isJSON(obj) {
        return !!(obj && obj.constructor === objC);
    }
    
    var arrC = [].constructor;
    function isArr(arr) {
        return !!(arr && arr.constructor === arrC);
    }
    
    function merge(json1,json2) {
        var result = null;
        if(isJSON(json2)){
            result = {};
            if(isJSON(json1)){
                for(var key in json1){
                    if(json1.hasOwnProperty(key)){
                        result[key] = json1[key];
                    }
                }
            }
    
            for(key in json2){
                if(json2.hasOwnProperty(key)){
                    if(typeof result[key] === 'object' && typeof json2[key] === 'object'){
                        result[key] = merge(result[key],json2[key]);
                    }else{
                        result[key] = json2[key];
                    }
                }
            }
        }else if(isArr(json1) && isArr(json2)){
            result = json1;
            json2.forEach(function (t) {
                if(result.indexOf(t) === -1){
                    result.push(t);
                }
            })
        }else{
            result = json2;
        }
        return result;
    }
    

    起源地下载网 » 常用的js 方法

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元