javescript utils

提高网站性能, 尽量保证首屏幕的稳定,尽量不用js来设置偏移量

lighthouse 分析工具 seo

防抖 

export function debounce(func, wait, immediate) {
  let timeout, args, context, timestamp, result

  const later = function() {
    // 据上一次触发时间间隔
    const last = +new Date() - timestamp

    // 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait
    if (last < wait && last > 0) {
      timeout = setTimeout(later, wait - last)
    } else {
      timeout = null
      // 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用
      if (!immediate) {
        result = func.apply(context, args)
        if (!timeout) context = args = null
      }
    }
  }
  return function(...args) {
    context = this
    timestamp = +new Date()
    const callNow = immediate && !timeout
    // 如果延时不存在,重新设定延时
    if (!timeout) timeout = setTimeout(later, wait)
    if (callNow) {
      result = func.apply(context, args)
      context = args = null
    }

    return result
  }
}

多个window.resize 冲突问题

// 监听窗口改变
window.addEventListener('resize', function() {})
//要加防抖哦!
window.addEventListener('resize', debounce(function() {}, 500))

//监听滚动方法
window.addEventListener("scroll", debounce(function() {}, 200))

只能保留两位小数点 小数点验证

export const clearNum = (value) => {
  let _val = value || ''
 _val = _val.replace(/[^\d.]/g,"")
 _val = _val.replace(/\.{2,}/g,".")
 _val = _val.replace(/^\./g,"");
 _val = _val.replace(".","$#$").replace(/\./g,"").replace("$#$",".");
 _val = _val.replace(/^(\-)*(\d+)\.(\d\d).*$/,'$1$2.$3');
 return _val
}

保留两位小数并去掉尾数为0的数字

如果返回的是这种: 0.10, 0.200,0.33 paresFloat可以很好的处理 为0.1, 0.2, 0.33

// 四舍五入var num =2.2354234234;num = num.toFixed(2);console.log('num=', num);

Math.floor() —— 先将小数变整数,然后再保留小数位数 

//不四舍五入 var num2 = Math.floor(2.2344234234 * 100) / 100

获取经纬度的距离

export function GetDistance( lat1,  lng1,  lat2,  lng2, number){
  if(!lat1 || !lng1 || !lat2 ||!lng2) {
    return ''
  }
  var radLat1 = lat1*Math.PI / 180.0;
  var radLat2 = lat2*Math.PI / 180.0;
  var a = radLat1 - radLat2;
  var  b = lng1*Math.PI / 180.0 - lng2*Math.PI / 180.0;
  var s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a/2), 2) +
  Math.cos(radLat1)*Math.cos(radLat2)*Math.pow(Math.sin(b/2), 2)));
  s = s *6378.137 ;// EARTH_RADIUS;
  s = Math.round(s * number) / number;
  return s + 'km';
}

// 解决精度方案var num5 = 8.54342345;var numStr = num5.toString();var idx = numStr.indexOf('.');var res = Number(numStr.slice(0, idx + 3));console.log('res=',res);

cookie utile 

class CookieUtil {
    static getItem(sKey) {
        return (
            unescape(
                document.cookie.replace(
                    new RegExp(
                        "(?:(?:^|.*;)\\s*" +
                        escape(sKey).replace(/[-.+*]/g, "\\$&") +
                        "\\s*\\=\\s*([^;]*).*$)|^.*$"
                    ),
                    "$1"
                )
            ) || null
        );
    }

    static setItem(sKey, sValue, vEnd, sPath, sDomain, bSecure) {
        if (!sKey || /^(?:expires|max-age|path|domain|secure)$/i.test(sKey)) {
            return false;
        }
        var sExpires = "";
        if (vEnd) {
            switch (vEnd.constructor) {
                case Number:
                    sExpires =
                        vEnd === Infinity ?
                        "; expires=Fri, 31 Dec 9999 23:59:59 GMT" :
                        "; max-age=" + vEnd;
                    break;
                case String:
                    sExpires = "; expires=" + vEnd;
                    break;
                case Date:
                    sExpires = "; expires=" + vEnd.toUTCString();
                    break;
            }
        }
        document.cookie =
            escape(sKey) +
            "=" +
            escape(sValue) +
            sExpires +
            (sDomain ? "; domain=" + sDomain : "") +
            (sPath ? "; path=" + sPath : ";path=/") +
            (bSecure ? "; secure" : "");
        return true;
    }

    static removeItem(sKey, sDomain, sPath) {
        var exp = new Date();
        exp.setTime(exp.getTime() - 1);
        var cval = this.getItem(sKey);
        if (cval != null) {
            document.cookie =
                escape(sKey) +
                "=" +
                cval +
                ";expires=" +
                exp.toUTCString() +
                (sDomain ? ";domain=" + sDomain : "") +
                (sPath ? ";path=" + sPath : ";path=/");

            // console.log(escape(sKey) +
            //   "=" +
            //   cval +
            //   ";expires=" +
            //   exp.toUTCString() +
            //   (sDomain ? ";domain=" + sDomain : "") + (sPath ? ";path=" + sPath : ";path=/"));
        }

        return true;
    }

    static hasItem(sKey) {
        return new RegExp(
            "(?:^|;\\s*)" + escape(sKey).replace(/[-.+*]/g, "\\$&") + "\\s*\\="
        ).test(document.cookie);
    }

    static keys() {
        var aKeys = document.cookie
            .replace(/((?:^|\s*;)[^=]+)(?=;|$)|^\s*|\s*(?:=[^;]*)?(?:\1|$)/g, "")
            .split(/\s*(?:=[^;]*)?;\s*/);
        for (var nIdx = 0; nIdx < aKeys.length; nIdx++) {
            aKeys[nIdx] = unescape(aKeys[nIdx]);
        }
        return aKeys;
    }
}

getuuid 

function getUUID(len, radix) {
    var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('')
    var uuid = []
    var i
    radix = radix || chars.length
    if (len) {
      for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix]
    } else {
      var r
      uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-'
      uuid[14] = '4'
      for (i = 0; i < 36; i++) {
        if (!uuid[i]) {
          r = 0 | Math.random() * 16
          uuid[i] = chars[(i === 19) ? (r & 0x3) | 0x8 : r]
        }
      }
    }
    return uuid.join('')
}

matrix(3d)

function getTransformByMatrix(translateString) {
  var matrix = translateString.match(/matrix(3d)?\((.+?)\)/);
  var is3D = matrix && matrix[1];
  if (matrix) {
      matrix = matrix[2].split(",");
      if (is3D === "3d")
          matrix = matrix.slice(12, 15);
      else {
          matrix.push(0);
          matrix = matrix.slice(4, 7);
      }
  } else {
      matrix = [0, 0, 0];
  }
  var result = {
      x: parseFloat(matrix[0]),
      y: parseFloat(matrix[1]),
      z: parseFloat(matrix[2])
  };
  return result;
}
代码段
let translates = $('.xxxx').css('transform')
let obj = getTransformByMatrix(translates)
Math.abs()取绝对值

图片加载完成之后获取图片宽高信息 与 img src 与background-image 区别

页面元素内容最关键的一点就是,当css未加载时能看出这是什么

img src 是一个dom对象

网页加载顺序不一样

background-image 会等到dom结构加载完成才开始加载,先加载标签内容,再加载背景图片,不影响网页内容

img src在加载大图时,图片未加载完成,img后的内容都不会显示。影响浏览网页内容。

 const teemoimgLoad =  (v) => {
          return new Promise(resolve => {
            const img = new Image()
            img.src = v
            img.onload = () => resolve({width: img.width || '', height: img.height || ''})
          })
        }

获取文件

const convertFileToBase64 = (file) =>
  new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.readAsDataURL(file.rawFile);
    reader.onload = () => resolve(reader.result);
    reader.onerror = reject;
});
 const add = () => {

    return Promise.resolve(convertFileToBase64(myFile))
        .then((picture64) => ({
          src: picture64,
          title: `${myFile.title}`,
        }))
        .then((transformedMyFile) =>
          requestHandler(type, resource, {
            ...params,
            data: {
              ...params.data,
              myFile: transformedMyFile,
            },
          })
        );
}

获取url参数

//获取url参数
function getURLparam(key){
    var qstring = window.location.search;
    if (!qstring) return (!key || key == '*') ? {} : null;
    qstring = qstring.replace(/%20/g, ' ');
    qstring = qstring.substr(1); // remove ?
    var param = qstring.split('&');
    var map = new Object();
    for (var i = 0, j = param.length; i < j; i++){ var pl=param[i].split('='); map[pl[0]] = pl[1]; }
    return (!key || key == '*') ? map : map[key];
};

原型实例 可忽略

 // 公共方法 控制弹窗延时展示展示
    function changeNewsletterPopup() {
      this._newsPopupId = document.querySelector('#id') || ''
      this._newsPopupHead= document.querySelector("#id.heading") || ''
      this._newsPopupContent= document.querySelector("#id .content") || ''
      this.onlineTimes= [
        {
          title: "title1",
          content: "content1",
        },
        {
          title: "title2", 
          content: "content2",
        }
      ]
    }
    changeNewsletterPopup.prototype = {
      init: function (index, delayTime) {  //索引 和延迟时间
        if((index + 1)  > this.onlineTimes.length) {
          return false
        }
        if(this._newsPopupId) {
          if(!delayTime) {
            this._newsPopupHead.innerHTML = this.onlineTimes[index].title
            return false
          } else {
            this._newsPopupId.style.visibility = "hidden";
          }
          if(this._newsPopupHead) {
            this._newsPopupHead.innerHTML = this.onlineTimes[index].title
          }
          if(this._newsPopupContent) {
            this._newsPopupContent.innerHTML = this.onlineTimes[index].content
          }
          let newsPopupTime = setTimeout(()=>{
            this._newsPopupId.style.visibility = "visible";
              clearTimeout(newsPopupTime)  	                 
          }, delayTime);
        } else {
        } 
      } 
    }
    // 控制弹窗的弹出 定制化
    if(pathNameCalculate === "page1") {
      const test1 = new changeNewsletterPopup()
      changeNewsletterPopupXbike.init(0, 30000)
    } else if(pathNameCalculate === "page2") {
      const test2 = new changeNewsletterPopup()
      changeNewsletterPopupProductsXbike.init(0, 80000)
    }

H5 safri返回时无法自动播放视频

 <video class="pc-video js-videoPlayer"  
        x-webkit-airplay="allow" webkit-playsinline="true" 
        playsinline="true" 
        autoplay="autoplay" 
        muted="muted" 
        loop="loop" 
        src="https://xxx.mp4?">
</video>
<script type="text/javascript">
  $(function() {
    $('body').on('click', '.js-slideshow-index', function (e) { 
      customGaEvent('home-banner-scrool', 'click', 'banner' + $(this).data('number'))
    })
  })
  function playBySeconds () {
    console.log('33333')
    $('.js-videoPlayer').trigger('play')
  }
  function hideVedio() {
    console.log('hideVedio')
    console.log('$', $('.js-videoPlayer'))
    $('.js-videoPlayer').trigger('pause')
  }
  window.addEventListener('pageshow', function() {
       console.log('pageshow')
      playBySeconds()
  });
  window.addEventListener('pagehide', function() {
    console.log('pagehide')
    hideVedio()
  });
  document.addEventListener('visibilitychange', async () => {
    if (document.visibilityState == 'visible') {
      console.log("visibilitychange show")
      playBySeconds()
    } else {
      hideVedio()
      console.log("visibilitychange hide")
    }
  })
</script>

动态插入js

    this.insertScript = function (src, id) {
        const script = document.createElement("script");
        script.setAttribute("id", id);
        script.setAttribute("src", src);
        script.setAttribute("async", "async");
        document.body.appendChild(script);
        return _this;
    };

IOS浏览器导航栏和底部工具栏 100vh正确使用方式: 100vh包括导航栏和底部底部工具栏高度,但对于fixed 属性 100vh就包含导航栏和工具栏的高度, 这个时候只要在body 后面铺一层 fixed div元素,然后获取这个真实高度, 直接放到我们场景动画高度, 完美解决 ios浏览器底部工具栏有时出现有时不会出现的问题

.fixed-animation-ios{
    position: fixed;
    left: 0;
    top: 0;
    bottom: 0;
    right: 0;
    width: 100%;
    height: 100vh;
    z-index: -100;
}
<div class="fixed-animation-ios">
</div>

var iosMaxheight= ($('.fixed-animation-ios').length > 0)? $('.fixed-animation-ios').innerHeight() : window.innerHeight

彩虹rgba颜色

1、赤色【RGB】  rgba(255,0,0,1) ,  rgba(255,0,0,0.1)
2、橙色【RGB】  rgba(255,165,0,1) ,  rgba(255,165,0,0.1)
3、黄色【RGB】  rgba(255,255,0,1) , rgba(255,255,0,0.1)
4、绿色【RGB】  rgba(0,255,0,1) ,  rgba(0,255,0,1 0.1)
5、青色【RGB】  rgba(0,127,255,1) , rgba(0,127,255,0.1)
6、蓝色【RGB】  rgba(0,0,255,1), rgba(0,0,255,0.1)
7、紫色【RGB】 rgba(139,0,255,1),   rgba(139,0,255,0.1)

字符串倒数第二位加上小数点

var price = 109000
price = price.toString()
price = price.slice(0,price.length -2) + "." + price.slice(price.length -2) //1090.00

 建立观察者模式

    const initBuyButoon = {
      deviceId: getPcOrMobile(),
      isInit: false,
      isUnbrand: false,
      init: function () {
        this.event()
      },
      scrollBtn: function ($dom) {
        let xbikeAddToCart = document.getElementById('xbike-add-to-cart-main');
              let observerBtn = new IntersectionObserver(function(entries){
               // 监听元素是否在可视区域内
                entries.forEach( function(element, index) {
                    if (element.isIntersecting ) {
                      if($dom.css('position') !== 'static') {
                        $dom.css('position', 'static')
                        $dom.removeClass('shopify-payment-button_position')
                      }
                    } else {
                      if($dom.css('position') !== 'fixed') { 
                        $dom.css('position', 'fixed')
                        $dom.addClass('shopify-payment-button_position')
                      }
                      
                    }
                });
            }, {
                root: null,
                threshold:[0, 1]
          });
          observerBtn.observe(xbikeAddToCart)
      },
      event: function () {
        let _this = this
        {% comment %} if(this.deviceId === 2 || window.innerWidth <= 640) { {% endcomment %}
          const targetNode = document.getElementsByClassName('shopify-payment-button')[0];
          // 当观察到突变时执行的回调函数
          let callback = function(mutationsList) {
              mutationsList.forEach(function(item,index){
                  if (item.type == 'childList') {
                      if($('.shopify-payment-button').find('.shopify-payment-button__button--branded').length > 0) {
                        if((_this.deviceId === 2 || window.innerWidth <= 640) && !_this.isInit){
                          _this.scrollBtn($('.shopify-payment-button').find('.shopify-payment-button__button--branded'))
                        }
                        _this.isInit = true
                      } else if($('.shopify-payment-button').find('.shopify-payment-button__button--unbranded').length > 0) {
                        if(!_this.isUnbrand) {
                          customGaEvent( 'buy-it-now-exposure', window.location.pathname, 'shopify-payment-button__button--unbranded')
                        }
                        _this.isUnbrand = true
                      }
                  }
              });
          };
      
          // 创建一个链接到回调函数的观察者实例 由于这个元素是三方插入的,需要监听什么时候从页面出现的
          const observerDom = new MutationObserver(callback);
      
          // 开始观察已配置突变的目标节点
          observerDom.observe(targetNode, { attributes: true, childList: true, subtree: true });
      
          // 停止观察
          //observer.disconnect();
        {% comment %} } {% endcomment %}
      }  
    }
    initBuyButoon.init()

去掉移动端点击后的背景色

-webkit-tap-highlight-color:transparent

点击弹窗之外关闭弹窗

$(document).bind("click",function(e){      
    if($(e.target).closest(".js-peleton-panel-name").length == 0){
        //点击id为menu之外且id不是不是open,则触发
        _this.closeFunc()
    }
    if($(e.target).closest(".js-freebeat-panel-name").length == 0){
        //点击id为menu之外且id不是不是open,则触发
        _this.closeFunc2('.js-freebeat-panel-name')
    }
})

短信分享

分享短信 ios的和安卓不太一样

ios 'sms:&body='+encodeURIComponent(shareText)

安卓 'sms:?body='+encodeURIComponent(encodeURIComponent(shareText))

判断是设备类型

let isIos = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/);

'Login | InCareer

// 阻止事件冒泡 停止传播
e.stopPropagation() 

事件冒泡 从下到上 从子元素到父元素 bottom-> div -> body ->dom

事件捕获 从上到下 从父元素向下捕获 dom->body->div-> button

事件委托 节约性能 li标签的点击委托到 ul上
 <ul>
    <li></li>
    <li></li>
</ul>

stopPropagation:阻止事件的冒泡和捕获。

因为事件可以在各层级的节点中传递, 不管是冒泡还是捕获, 有时我们希望事件在特定节点执行完之后不再传递, 可以使用事件对象的 stopPropagation() 方法。

preventDefault:阻止浏览器默认行为

浏览器的默认行为:对于一些特定的事件,浏览器有它默认的行为。

例如:

点击链接会进行跳转

点击鼠标右键会呼出浏览器右键菜单

填写表单时按回车会自动提交到服务器等

return false; 当你调用它时会做 3 件事:

event.preventDefault() – 它停止浏览器的默认行为。

event.stopPropagation() – 它阻止事件传播(或“冒泡”)DOM。

停止回调执行并立即返回。

监听点击事件的方法 包括 a标签跳转

if (window.innerWidth > 768) {
   attachEventsabHreoImage()
}
function eventDelegateCallbackabHeroImage(selector, callback, e) {
    const elements = Array.from(document.querySelectorAll(selector));
    for (let i = 0, len = elements.length; i < len; i++) {
        const el = elements[i];
        if ([e.target, e.target.closest(selector)].includes(el)) {
            callback.call(el, e);
            break;
        }
    }
}
function registerEventHreoImage(eventName) {
    console.log("eventName", eventName)
    window._fpEvent = window._fpEvent || [];
    window._fpEvent.push(["eventConversion", {value: eventName}]);
}
var lastTimeHeroImage=0
function attachEventsabHreoImage() {
    document.addEventListener('click', function (e) {
        if (new Date().getTime() - lastTimeHeroImage < 1000) {
            return;
        }
        lastTimeHeroImage = new Date().getTime();
            eventDelegateCallbackabHeroImage('.figpii-img-banner .js-public-gtm-btn', function () {
                if(this){
                    registerEventHreoImage('hreo_image_click_explore_bikes')
                }
         }, e)
    }, true)
}

控制频繁操作video播放和暂停

function playVideo (videodom){
    if(videodom.length > 0) {
        videodom.each(function(index,elemet) {
            let _isrc = $(elemet).attr('src')
            if(_isrc && elemet.paused) {
                let playPromise = elemet.play()
                if (playPromise !== undefined) {
                    playPromise.then(() => {
                        elemet.play()
                    }).catch(()=> {
                    
                    })
                }
                // elemet.play()
            }
        })
    }
}
function pausedVideo (videodom) {
    if(videodom.length > 0) {
        videodom.each(function(index, elemet) {
            let _isrc= $(elemet).attr('src')
            if(_isrc && !elemet.paused) {
                elemet.pause()
            }
        })
    }
}
let video_all = $(`.js-homebanner-slid[data-type=video_banner]`)
let _video2 = video_all.find('video')
pausedVideo(_video2)

获取宽度

let content = $("div").width();//只是获取content宽度
let contentWithPadding = $("div").innerWidth();//获取content+padding的宽度
let withoutMargin = $("div"). outerWidth();//获取content+padding+border的宽度
let full = $("div"). outerWidth(true);//获取content+padding+border+margin的宽度

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值