zoukankan      html  css  js  c++  java
  • JS节流与防抖

    节流防抖

    // 节流函数 (最后一次不执行)
    // 立即执行 在单位时间内只触发一次事件
    const throttle = (method, delay) => {
      let timer = null;
      let start = false;
      return function () {
        if (!start) {
          start = true;
          method.apply(this, arguments);
          timer = setTimeout(() => {
            start = false;
          }, delay);
        }
      };
    };
    
    // 节流函数(最后一次执行)
    // 立即执行 在单位时间内只触发一次事件 执行最后一次
    const throttle = (method, delay) => {
      let timer = null;
      let start = Date.now();
      return function () {
        let now = Date.now();
        clearTimeout(timer);
        if (now - start >= delay) {
          method.apply(this, arguments);
          start = now;
        } else {
          timer = setTimeout(() => {
            method.apply(this, arguments);
            start = Date.now();
          }, delay);
        }
      };
    };
    
    // 防抖函数(立即执行版)
    // 先执行一次 在事件被触发单位时间内 又被触发 则重新计时
    const debounce = (method, delay) => {
      let timer = null;
      let start = Date.now();
      return function () {
        let now = Date.now();
        clearTimeout(timer);
        if (now - start >= delay) {
          method.apply(this, arguments);
          start = now;
        } else {
          timer = setTimeout(() => {
            method.apply(this, arguments);
          }, delay);
          start = now;
        }
      };
    };
    
    // 防抖函数(延迟执行版)
    // 在事件被触发单位时间内 又被触发 则重新计时
    const debounce = (method, delay) => {
      let timer = null
      return function () {
        clearTimeout(timer)
        timer = setTimeout(() => {
          method.apply(this, arguments)
        }, delay)
      };
    };

     

    function isObject (value) {
      let type = typeof value;
      return value !== null && (type === 'object' || type === 'function')
    }
    const root = window;
    function now () {
      return root.Date.now()
    }
    let Symbol = root.Symbol;
    let objectProto = Object.prototype;
    let hasOwnProperty = objectProto.hasOwnProperty;
    let nativeObjectToString = objectProto.toString;
    let symToStringTag = Symbol ? Symbol.toStringTag : undefined;
    function getRawTag (value) {
      let isOwn = hasOwnProperty.call(value, symToStringTag);
      let tag = value[symToStringTag];
      let unmasked = false;
      try {
        value[symToStringTag] = undefined;
        unmasked = true;
      } catch (e) {
        return
      }
      let result = nativeObjectToString.call(value);
      if (unmasked) {
        if (isOwn) {
          value[symToStringTag] = tag;
        } else {
          delete value[symToStringTag];
        }
      }
      return result
    }
    let objectProto$1 = Object.prototype;
    let nativeObjectToString$1 = objectProto$1.toString;
    function objectToString (value) {
      return nativeObjectToString$1.call(value)
    }
    let nullTag = '[object Null]';
    let undefinedTag = '[object Undefined]';
    let symToStringTag$1 = Symbol ? Symbol.toStringTag : undefined;
    function baseGetTag (value) {
      if (value == null) {
        return value === undefined ? undefinedTag : nullTag
      }
      return (symToStringTag$1 && symToStringTag$1 in Object(value))
        ? getRawTag(value)
        : objectToString(value)
    }
    function isObjectLike (value) {
      return value !== null && typeof value === 'object'
    }
    const symbolTag = '[object Symbol]';
    function isSymbol (value) {
      return typeof value == 'symbol' ||
        (isObjectLike(value) && baseGetTag(value) === symbolTag)
    }
    let NAN = 0 / 0;
    let reTrim = /^s+|s+$/g;
    let reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
    let reIsBinary = /^0b[01]+$/i;
    let reIsOctal = /^0o[0-7]+$/i;
    let freeParseInt = parseInt;
    function toNumber (value) {
      if (typeof value == 'number') {
        return value
      }
      if (isSymbol(value)) {
        return NAN
      }
      if (isObject(value)) {
        let other = typeof value.valueOf === 'function' ? value.valueOf() : value;
        value = isObject(other) ? (other + '') : other;
      }
      if (typeof value !== 'string') {
        return value === 0 ? value : +value
      }
      value = value.replace(reTrim, '');
      let isBinary = reIsBinary.test(value);
      return (isBinary || reIsOctal.test(value))
        ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
        : (reIsBadHex.test(value) ? NAN : +value)
    }
    const nativeMax = Math.max;
    const nativeMin = Math.min;
    function debounce (func, wait, options) {
      let lastArgs;
      let lastThis;
      let maxWait;
      let result;
      let timerId;
      let lastCallTime;
      let lastInvokeTime = 0;
      let leading = false;
      let maxing = false;
      let trailing = true;
      if (typeof func !== 'function') {
        throw new TypeError('Expected a function')
      }
      wait = toNumber(wait) || 0;
      if (isObject(options)) {
        leading = !!options.leading;
        maxing = 'maxWait' in options;
        maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;
        trailing = 'trailing' in options ? !!options.trailing : trailing;
      }
      function invokeFunc (time) {
        let args = lastArgs;
        let thisArg = lastThis;
        lastArgs = lastThis = undefined;
        lastInvokeTime = time;
        result = func.apply(thisArg, args);
        return result
      }
      function leadingEdge (time) {
        lastInvokeTime = time;
        timerId = setTimeout(timerExpired, wait);
        return leading ? invokeFunc(time) : result
      }
      function remainingWait (time) {
        let timeSinceLastCall = time - lastCallTime;
        let timeSinceLastInvoke = time - lastInvokeTime;
        let timeWaiting = wait - timeSinceLastCall;
        return maxing
          ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke)
          : timeWaiting
      }
      function shouldInvoke (time) {
        let timeSinceLastCall = time - lastCallTime;
        let timeSinceLastInvoke = time - lastInvokeTime;
        return (lastCallTime === undefined || (timeSinceLastCall >= wait) ||
          (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait))
      }
      function timerExpired () {
        let time = now();
        if (shouldInvoke(time)) {
          return trailingEdge(time)
        }
        timerId = setTimeout(timerExpired, remainingWait(time));
      }
      function trailingEdge (time) {
        timerId = undefined;
        if (trailing && lastArgs) {
          return invokeFunc(time)
        }
        lastArgs = lastThis = undefined;
        return result
      }
      function cancel () {
        if (timerId !== undefined) {
          clearTimeout(timerId);
        }
        lastInvokeTime = 0;
        lastArgs = lastCallTime = lastThis = timerId = undefined;
      }
      function flush () {
        return timerId === undefined ? result : trailingEdge(now())
      }
      function debounced () {
        let time = now();
        let isInvoking = shouldInvoke(time);
        lastArgs = arguments;
        lastThis = this;
        lastCallTime = time;
        if (isInvoking) {
          if (timerId === undefined) {
            return leadingEdge(lastCallTime)
          }
          if (maxing) {
            clearTimeout(timerId);
            timerId = setTimeout(timerExpired, wait);
            return invokeFunc(lastCallTime)
          }
        }
        if (timerId === undefined) {
          timerId = setTimeout(timerExpired, wait);
        }
        return result
      }
      debounced.cancel = cancel;
      debounced.flush = flush;
      return debounced
    }
    function throttle (func, wait, options) {
      let leading = true;
      let trailing = true;
      if (typeof func !== 'function') {
        throw new TypeError('Expected a function')
      }
      if (isObject(options)) {
        leading = 'leading' in options ? !!options.leading : leading;
        trailing = 'trailing' in options ? !!options.trailing : trailing;
      }
      return debounce(func, wait, {
        'leading': leading,
        'maxWait': wait,
        'trailing': trailing
      })
    }
  • 相关阅读:
    Vue 封装js 并 引用
    Vue todolist练习 知识点
    Vue 双向数据绑定、事件介绍以及ref获取dom节点
    Vue 目录结构 绑定数据 绑定属性 循环渲染数据
    Vue自学笔记--项目的创建
    sqlalchemy第一部分
    mysql查询补充
    mysql数据库查询操作
    mysql数据库关系操作
    数据表的约束及数据类型操作
  • 原文地址:https://www.cnblogs.com/QQPrincekin/p/12456646.html
Copyright © 2011-2022 走看看