/** * UNDERSCORE.JS 部分源码(有修改) 防抖节流 */ var restArguments = function (func, startIndex) { startIndex = startIndex == null ? func.length - 1 : +startIndex; return function () { var length = Math.max(arguments.length - startIndex, 0), rest = Array(length), index = 0; for (; index < length; index++) { rest[index] = arguments[index + startIndex]; } switch (startIndex) { case 0: return func.call(this, rest); case 1: return func.call(this, arguments[0], rest); case 2: return func.call(this, arguments[0], arguments[1], rest); } var args = Array(startIndex + 1); for (index = 0; index < startIndex; index++) { args[index] = arguments[index]; } args[startIndex] = rest; return func.apply(this, args); }; }; var delay = restArguments(function (func, wait, args) { return setTimeout(function () { return func.apply(null, args); }, wait); }); var now = Date.now || function () { return new Date().getTime(); }; /* 默认 在 wait 间隔结束时,将使用最近传递给 debounced(去抖动)函数的参数调用该函数 参数: immediate 为 true, debounce会在 wait 时间间隔的开始调用这个函数,反之在 wait 间隔结束时调用这个函数 属性 cancel:如果需要取消预定的 debounce ,可以在 debounce 函数上调用 .cancel()。 返回值类型 Function */ var debounce = function (func, wait, immediate) { var timeout, result; var later = function (context, args) { timeout = null; if (args) result = func.apply(context, args); }; var debounced = restArguments(function (args) { if (timeout) clearTimeout(timeout); if (immediate) { var callNow = !timeout; timeout = setTimeout(later, wait); if (callNow) result = func.apply(this, args); } else { timeout = delay(later, wait, this, args); } return result; }); debounced.cancel = function () { clearTimeout(timeout); timeout = null; }; return debounced; }; /* 默认 在你调用的第一时间尽快执行这个function,并且,如果你在wait周期内调用任意次数的函数,都将尽快的被覆盖。 参数 options:{ leading: 如果你想禁用第一次首先执行的话,传递 {leading: false} trailing: 如果你想禁用最后一次执行的话,传递 {trailing: false} } 属性 cancel:如果需要取消预定的 throttle ,可以在 throttle 函数上调用 .cancel()。 返回值类型 Function */ var throttle = function (func, wait, options) { var timeout, context, args, result; var previous = 0; if (!options) options = {}; var later = function () { previous = options.leading === false ? 0 : now(); timeout = null; result = func.apply(context, args); if (!timeout) context = args = null; }; var throttled = function () { var now = now(); if (!previous && options.leading === false) previous = now; var remaining = wait - (now - previous); context = this; args = arguments; if (remaining <= 0 || remaining > wait) { if (timeout) { clearTimeout(timeout); timeout = null; } previous = now; result = func.apply(context, args); if (!timeout) context = args = null; } else if (!timeout && options.trailing !== false) { timeout = setTimeout(later, remaining); } return result; }; throttled.cancel = function () { clearTimeout(timeout); previous = 0; timeout = context = args = null; }; return throttled; }; export { debounce, throttle };