当前位置:   article > 正文

JS中防抖函数介绍与实现(秒懂如何手写防抖)_手写防抖函数

手写防抖函数

目录

一、认识防抖函数

1.防抖函数的概念

2.防抖函数原理

3.防抖函数的好处

二、防抖函数的实现

1.CDN引入实现

2.本地引入实现

 3.手写防抖(初步实现)

 4.手写防抖(高级实现)

5.实现防抖-获取返回值

三、防抖函数的应用

四、最终实现函数封装


一、认识防抖函数

1.防抖函数的概念

函数防抖是一种用于限制函数执行频率的技术。在JavaScript中,函数防抖常用于处理频繁触发的事件,如浏览器窗口的resize事件、滚动事件、输入框的输入事件等。它通过延迟函数的执行来确保在一定时间内只执行一次。

2.防抖函数原理

1.当事件被触发时,不立即执行事件处理函数,而是等待一段时间(延迟时间)。

2.如果在这段时间内事件再次被触发,则重新计时,延迟时间重新开始计算。

3.直到延迟时间内没有再次触发事件,才执行事件处理函数。

3.防抖函数的好处

可以避免频繁触发事件造成不必要的资源消耗或执行结果混乱的情况,而只关注最后一次触发事件的结果。

二、防抖函数的实现

1.CDN引入实现

打开Underscore.js网站,找到CDN URLs,复制其中js文件地址引入即可。

<input type="text">
  1. <!-- CDN引入:网络的js文件 -->
  2. <script src="https://cdn.jsdelivr.net/npm/underscore@1.13.6/underscore-umd-min.js"></script>
  3. let counter = 1
  4. inputEl.oninput = _.debounce(function(){
  5. console.log(`发送网络请求${counter++}:`,this.value)
  6. },500)

2.本地引入实现

Underscore.js网站中的js文件下载到本地,并进行版本引入。

例如:1.13.6版本

  1. !function (n, r) { "object" == typeof exports && "undefined" != typeof module ? module.exports = r() : "function" == typeof define && define.amd ? define("underscore", r) : (n = "undefined" != typeof globalThis ? globalThis : n || self, function () { var t = n._, e = n._ = r(); e.noConflict = function () { return n._ = t, e } }()) }(this, (function () {
  2. // Underscore.js 1.13.6
  3. // https://underscorejs.org
  4. // (c) 2009-2022 Jeremy Ashkenas, Julian Gonggrijp, and DocumentCloud and Investigative Reporters & Editors
  5. // Underscore may be freely distributed under the MIT license.
  6. var n = "1.13.6", r = "object" == typeof self && self.self === self && self || "object" == typeof global && global.global === global && global || Function("return this")() || {}, t = Array.prototype, e = Object.prototype, u = "undefined" != typeof Symbol ? Symbol.prototype : null, o = t.push, i = t.slice, a = e.toString, f = e.hasOwnProperty, c = "undefined" != typeof ArrayBuffer, l = "undefined" != typeof DataView, s = Array.isArray, p = Object.keys, v = Object.create, h = c && ArrayBuffer.isView, y = isNaN, d = isFinite, g = !{ toString: null }.propertyIsEnumerable("toString"), b = ["valueOf", "isPrototypeOf", "toString", "propertyIsEnumerable", "hasOwnProperty", "toLocaleString"], m = Math.pow(2, 53) - 1; function j(n, r) { return r = null == r ? n.length - 1 : +r, function () { for (var t = Math.max(arguments.length - r, 0), e = Array(t), u = 0; u < t; u++)e[u] = arguments[u + r]; switch (r) { case 0: return n.call(this, e); case 1: return n.call(this, arguments[0], e); case 2: return n.call(this, arguments[0], arguments[1], e) }var o = Array(r + 1); for (u = 0; u < r; u++)o[u] = arguments[u]; return o[r] = e, n.apply(this, o) } } function _(n) { var r = typeof n; return "function" === r || "object" === r && !!n } function w(n) { return void 0 === n } function A(n) { return !0 === n || !1 === n || "[object Boolean]" === a.call(n) } function x(n) { var r = "[object " + n + "]"; return function (n) { return a.call(n) === r } } var S = x("String"), O = x("Number"), M = x("Date"), E = x("RegExp"), B = x("Error"), N = x("Symbol"), I = x("ArrayBuffer"), T = x("Function"), k = r.document && r.document.childNodes; "function" != typeof /./ && "object" != typeof Int8Array && "function" != typeof k && (T = function (n) { return "function" == typeof n || !1 }); var D = T, R = x("Object"), F = l && R(new DataView(new ArrayBuffer(8))), V = "undefined" != typeof Map && R(new Map), P = x("DataView"); var q = F ? function (n) { return null != n && D(n.getInt8) && I(n.buffer) } : P, U = s || x("Array"); function W(n, r) { return null != n && f.call(n, r) } var z = x("Arguments"); !function () { z(arguments) || (z = function (n) { return W(n, "callee") }) }(); var L = z; function $(n) { return O(n) && y(n) } function C(n) { return function () { return n } } function K(n) { return function (r) { var t = n(r); return "number" == typeof t && t >= 0 && t <= m } } function J(n) { return function (r) { return null == r ? void 0 : r[n] } } var G = J("byteLength"), H = K(G), Q = /\[object ((I|Ui)nt(8|16|32)|Float(32|64)|Uint8Clamped|Big(I|Ui)nt64)Array\]/; var X = c ? function (n) { return h ? h(n) && !q(n) : H(n) && Q.test(a.call(n)) } : C(!1), Y = J("length"); function Z(n, r) { r = function (n) { for (var r = {}, t = n.length, e = 0; e < t; ++e)r[n[e]] = !0; return { contains: function (n) { return !0 === r[n] }, push: function (t) { return r[t] = !0, n.push(t) } } }(r); var t = b.length, u = n.constructor, o = D(u) && u.prototype || e, i = "constructor"; for (W(n, i) && !r.contains(i) && r.push(i); t--;)(i = b[t]) in n && n[i] !== o[i] && !r.contains(i) && r.push(i) } function nn(n) { if (!_(n)) return []; if (p) return p(n); var r = []; for (var t in n) W(n, t) && r.push(t); return g && Z(n, r), r } function rn(n, r) { var t = nn(r), e = t.length; if (null == n) return !e; for (var u = Object(n), o = 0; o < e; o++) { var i = t[o]; if (r[i] !== u[i] || !(i in u)) return !1 } return !0 } function tn(n) { return n instanceof tn ? n : this instanceof tn ? void (this._wrapped = n) : new tn(n) } function en(n) { return new Uint8Array(n.buffer || n, n.byteOffset || 0, G(n)) } tn.VERSION = n, tn.prototype.value = function () { return this._wrapped }, tn.prototype.valueOf = tn.prototype.toJSON = tn.prototype.value, tn.prototype.toString = function () { return String(this._wrapped) }; var un = "[object DataView]"; function on(n, r, t, e) { if (n === r) return 0 !== n || 1 / n == 1 / r; if (null == n || null == r) return !1; if (n != n) return r != r; var o = typeof n; return ("function" === o || "object" === o || "object" == typeof r) && function n(r, t, e, o) { r instanceof tn && (r = r._wrapped); t instanceof tn && (t = t._wrapped); var i = a.call(r); if (i !== a.call(t)) return !1; if (F && "[object Object]" == i && q(r)) { if (!q(t)) return !1; i = un } switch (i) { case "[object RegExp]": case "[object String]": return "" + r == "" + t; case "[object Number]": return +r != +r ? +t != +t : 0 == +r ? 1 / +r == 1 / t : +r == +t; case "[object Date]": case "[object Boolean]": return +r == +t; case "[object Symbol]": return u.valueOf.call(r) === u.valueOf.call(t); case "[object ArrayBuffer]": case un: return n(en(r), en(t), e, o) }var f = "[object Array]" === i; if (!f && X(r)) { if (G(r) !== G(t)) return !1; if (r.buffer === t.buffer && r.byteOffset === t.byteOffset) return !0; f = !0 } if (!f) { if ("object" != typeof r || "object" != typeof t) return !1; var c = r.constructor, l = t.constructor; if (c !== l && !(D(c) && c instanceof c && D(l) && l instanceof l) && "constructor" in r && "constructor" in t) return !1 } o = o || []; var s = (e = e || []).length; for (; s--;)if (e[s] === r) return o[s] === t; if (e.push(r), o.push(t), f) { if ((s = r.length) !== t.length) return !1; for (; s--;)if (!on(r[s], t[s], e, o)) return !1 } else { var p, v = nn(r); if (s = v.length, nn(t).length !== s) return !1; for (; s--;)if (p = v[s], !W(t, p) || !on(r[p], t[p], e, o)) return !1 } return e.pop(), o.pop(), !0 }(n, r, t, e) } function an(n) { if (!_(n)) return []; var r = []; for (var t in n) r.push(t); return g && Z(n, r), r } function fn(n) { var r = Y(n); return function (t) { if (null == t) return !1; var e = an(t); if (Y(e)) return !1; for (var u = 0; u < r; u++)if (!D(t[n[u]])) return !1; return n !== hn || !D(t[cn]) } } var cn = "forEach", ln = "has", sn = ["clear", "delete"], pn = ["get", ln, "set"], vn = sn.concat(cn, pn), hn = sn.concat(pn), yn = ["add"].concat(sn, cn, ln), dn = V ? fn(vn) : x("Map"), gn = V ? fn(hn) : x("WeakMap"), bn = V ? fn(yn) : x("Set"), mn = x("WeakSet"); function jn(n) { for (var r = nn(n), t = r.length, e = Array(t), u = 0; u < t; u++)e[u] = n[r[u]]; return e } function _n(n) { for (var r = {}, t = nn(n), e = 0, u = t.length; e < u; e++)r[n[t[e]]] = t[e]; return r } function wn(n) { var r = []; for (var t in n) D(n[t]) && r.push(t); return r.sort() } function An(n, r) { return function (t) { var e = arguments.length; if (r && (t = Object(t)), e < 2 || null == t) return t; for (var u = 1; u < e; u++)for (var o = arguments[u], i = n(o), a = i.length, f = 0; f < a; f++) { var c = i[f]; r && void 0 !== t[c] || (t[c] = o[c]) } return t } } var xn = An(an), Sn = An(nn), On = An(an, !0); function Mn(n) { if (!_(n)) return {}; if (v) return v(n); var r = function () { }; r.prototype = n; var t = new r; return r.prototype = null, t } function En(n) { return U(n) ? n : [n] } function Bn(n) { return tn.toPath(n) } function Nn(n, r) { for (var t = r.length, e = 0; e < t; e++) { if (null == n) return; n = n[r[e]] } return t ? n : void 0 } function In(n, r, t) { var e = Nn(n, Bn(r)); return w(e) ? t : e } function Tn(n) { return n } function kn(n) { return n = Sn({}, n), function (r) { return rn(r, n) } } function Dn(n) { return n = Bn(n), function (r) { return Nn(r, n) } } function Rn(n, r, t) { if (void 0 === r) return n; switch (null == t ? 3 : t) { case 1: return function (t) { return n.call(r, t) }; case 3: return function (t, e, u) { return n.call(r, t, e, u) }; case 4: return function (t, e, u, o) { return n.call(r, t, e, u, o) } }return function () { return n.apply(r, arguments) } } function Fn(n, r, t) { return null == n ? Tn : D(n) ? Rn(n, r, t) : _(n) && !U(n) ? kn(n) : Dn(n) } function Vn(n, r) { return Fn(n, r, 1 / 0) } function Pn(n, r, t) { return tn.iteratee !== Vn ? tn.iteratee(n, r) : Fn(n, r, t) } function qn() { } function Un(n, r) { return null == r && (r = n, n = 0), n + Math.floor(Math.random() * (r - n + 1)) } tn.toPath = En, tn.iteratee = Vn; var Wn = Date.now || function () { return (new Date).getTime() }; function zn(n) { var r = function (r) { return n[r] }, t = "(?:" + nn(n).join("|") + ")", e = RegExp(t), u = RegExp(t, "g"); return function (n) { return n = null == n ? "" : "" + n, e.test(n) ? n.replace(u, r) : n } } var Ln = { "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#x27;", "`": "&#x60;" }, $n = zn(Ln), Cn = zn(_n(Ln)), Kn = tn.templateSettings = { evaluate: /<%([\s\S]+?)%>/g, interpolate: /<%=([\s\S]+?)%>/g, escape: /<%-([\s\S]+?)%>/g }, Jn = /(.)^/, Gn = { "'": "'", "\\": "\\", "\r": "r", "\n": "n", "\u2028": "u2028", "\u2029": "u2029" }, Hn = /\\|'|\r|\n|\u2028|\u2029/g; function Qn(n) { return "\\" + Gn[n] } var Xn = /^\s*(\w|\$)+\s*$/; var Yn = 0; function Zn(n, r, t, e, u) { if (!(e instanceof r)) return n.apply(t, u); var o = Mn(n.prototype), i = n.apply(o, u); return _(i) ? i : o } var nr = j((function (n, r) { var t = nr.placeholder, e = function () { for (var u = 0, o = r.length, i = Array(o), a = 0; a < o; a++)i[a] = r[a] === t ? arguments[u++] : r[a]; for (; u < arguments.length;)i.push(arguments[u++]); return Zn(n, e, this, this, i) }; return e })); nr.placeholder = tn; var rr = j((function (n, r, t) { if (!D(n)) throw new TypeError("Bind must be called on a function"); var e = j((function (u) { return Zn(n, e, r, this, t.concat(u)) })); return e })), tr = K(Y); function er(n, r, t, e) { if (e = e || [], r || 0 === r) { if (r <= 0) return e.concat(n) } else r = 1 / 0; for (var u = e.length, o = 0, i = Y(n); o < i; o++) { var a = n[o]; if (tr(a) && (U(a) || L(a))) if (r > 1) er(a, r - 1, t, e), u = e.length; else for (var f = 0, c = a.length; f < c;)e[u++] = a[f++]; else t || (e[u++] = a) } return e } var ur = j((function (n, r) { var t = (r = er(r, !1, !1)).length; if (t < 1) throw new Error("bindAll must be passed function names"); for (; t--;) { var e = r[t]; n[e] = rr(n[e], n) } return n })); var or = j((function (n, r, t) { return setTimeout((function () { return n.apply(null, t) }), r) })), ir = nr(or, tn, 1); function ar(n) { return function () { return !n.apply(this, arguments) } } function fr(n, r) { var t; return function () { return --n > 0 && (t = r.apply(this, arguments)), n <= 1 && (r = null), t } } var cr = nr(fr, 2); function lr(n, r, t) { r = Pn(r, t); for (var e, u = nn(n), o = 0, i = u.length; o < i; o++)if (r(n[e = u[o]], e, n)) return e } function sr(n) { return function (r, t, e) { t = Pn(t, e); for (var u = Y(r), o = n > 0 ? 0 : u - 1; o >= 0 && o < u; o += n)if (t(r[o], o, r)) return o; return -1 } } var pr = sr(1), vr = sr(-1); function hr(n, r, t, e) { for (var u = (t = Pn(t, e, 1))(r), o = 0, i = Y(n); o < i;) { var a = Math.floor((o + i) / 2); t(n[a]) < u ? o = a + 1 : i = a } return o } function yr(n, r, t) { return function (e, u, o) { var a = 0, f = Y(e); if ("number" == typeof o) n > 0 ? a = o >= 0 ? o : Math.max(o + f, a) : f = o >= 0 ? Math.min(o + 1, f) : o + f + 1; else if (t && o && f) return e[o = t(e, u)] === u ? o : -1; if (u != u) return (o = r(i.call(e, a, f), $)) >= 0 ? o + a : -1; for (o = n > 0 ? a : f - 1; o >= 0 && o < f; o += n)if (e[o] === u) return o; return -1 } } var dr = yr(1, pr, hr), gr = yr(-1, vr); function br(n, r, t) { var e = (tr(n) ? pr : lr)(n, r, t); if (void 0 !== e && -1 !== e) return n[e] } function mr(n, r, t) { var e, u; if (r = Rn(r, t), tr(n)) for (e = 0, u = n.length; e < u; e++)r(n[e], e, n); else { var o = nn(n); for (e = 0, u = o.length; e < u; e++)r(n[o[e]], o[e], n) } return n } function jr(n, r, t) { r = Pn(r, t); for (var e = !tr(n) && nn(n), u = (e || n).length, o = Array(u), i = 0; i < u; i++) { var a = e ? e[i] : i; o[i] = r(n[a], a, n) } return o } function _r(n) { var r = function (r, t, e, u) { var o = !tr(r) && nn(r), i = (o || r).length, a = n > 0 ? 0 : i - 1; for (u || (e = r[o ? o[a] : a], a += n); a >= 0 && a < i; a += n) { var f = o ? o[a] : a; e = t(e, r[f], f, r) } return e }; return function (n, t, e, u) { var o = arguments.length >= 3; return r(n, Rn(t, u, 4), e, o) } } var wr = _r(1), Ar = _r(-1); function xr(n, r, t) { var e = []; return r = Pn(r, t), mr(n, (function (n, t, u) { r(n, t, u) && e.push(n) })), e } function Sr(n, r, t) { r = Pn(r, t); for (var e = !tr(n) && nn(n), u = (e || n).length, o = 0; o < u; o++) { var i = e ? e[o] : o; if (!r(n[i], i, n)) return !1 } return !0 } function Or(n, r, t) { r = Pn(r, t); for (var e = !tr(n) && nn(n), u = (e || n).length, o = 0; o < u; o++) { var i = e ? e[o] : o; if (r(n[i], i, n)) return !0 } return !1 } function Mr(n, r, t, e) { return tr(n) || (n = jn(n)), ("number" != typeof t || e) && (t = 0), dr(n, r, t) >= 0 } var Er = j((function (n, r, t) { var e, u; return D(r) ? u = r : (r = Bn(r), e = r.slice(0, -1), r = r[r.length - 1]), jr(n, (function (n) { var o = u; if (!o) { if (e && e.length && (n = Nn(n, e)), null == n) return; o = n[r] } return null == o ? o : o.apply(n, t) })) })); function Br(n, r) { return jr(n, Dn(r)) } function Nr(n, r, t) { var e, u, o = -1 / 0, i = -1 / 0; if (null == r || "number" == typeof r && "object" != typeof n[0] && null != n) for (var a = 0, f = (n = tr(n) ? n : jn(n)).length; a < f; a++)null != (e = n[a]) && e > o && (o = e); else r = Pn(r, t), mr(n, (function (n, t, e) { ((u = r(n, t, e)) > i || u === -1 / 0 && o === -1 / 0) && (o = n, i = u) })); return o } var Ir = /[^\ud800-\udfff]|[\ud800-\udbff][\udc00-\udfff]|[\ud800-\udfff]/g; function Tr(n) { return n ? U(n) ? i.call(n) : S(n) ? n.match(Ir) : tr(n) ? jr(n, Tn) : jn(n) : [] } function kr(n, r, t) { if (null == r || t) return tr(n) || (n = jn(n)), n[Un(n.length - 1)]; var e = Tr(n), u = Y(e); r = Math.max(Math.min(r, u), 0); for (var o = u - 1, i = 0; i < r; i++) { var a = Un(i, o), f = e[i]; e[i] = e[a], e[a] = f } return e.slice(0, r) } function Dr(n, r) { return function (t, e, u) { var o = r ? [[], []] : {}; return e = Pn(e, u), mr(t, (function (r, u) { var i = e(r, u, t); n(o, r, i) })), o } } var Rr = Dr((function (n, r, t) { W(n, t) ? n[t].push(r) : n[t] = [r] })), Fr = Dr((function (n, r, t) { n[t] = r })), Vr = Dr((function (n, r, t) { W(n, t) ? n[t]++ : n[t] = 1 })), Pr = Dr((function (n, r, t) { n[t ? 0 : 1].push(r) }), !0); function qr(n, r, t) { return r in t } var Ur = j((function (n, r) { var t = {}, e = r[0]; if (null == n) return t; D(e) ? (r.length > 1 && (e = Rn(e, r[1])), r = an(n)) : (e = qr, r = er(r, !1, !1), n = Object(n)); for (var u = 0, o = r.length; u < o; u++) { var i = r[u], a = n[i]; e(a, i, n) && (t[i] = a) } return t })), Wr = j((function (n, r) { var t, e = r[0]; return D(e) ? (e = ar(e), r.length > 1 && (t = r[1])) : (r = jr(er(r, !1, !1), String), e = function (n, t) { return !Mr(r, t) }), Ur(n, e, t) })); function zr(n, r, t) { return i.call(n, 0, Math.max(0, n.length - (null == r || t ? 1 : r))) } function Lr(n, r, t) { return null == n || n.length < 1 ? null == r || t ? void 0 : [] : null == r || t ? n[0] : zr(n, n.length - r) } function $r(n, r, t) { return i.call(n, null == r || t ? 1 : r) } var Cr = j((function (n, r) { return r = er(r, !0, !0), xr(n, (function (n) { return !Mr(r, n) })) })), Kr = j((function (n, r) { return Cr(n, r) })); function Jr(n, r, t, e) { A(r) || (e = t, t = r, r = !1), null != t && (t = Pn(t, e)); for (var u = [], o = [], i = 0, a = Y(n); i < a; i++) { var f = n[i], c = t ? t(f, i, n) : f; r && !t ? (i && o === c || u.push(f), o = c) : t ? Mr(o, c) || (o.push(c), u.push(f)) : Mr(u, f) || u.push(f) } return u } var Gr = j((function (n) { return Jr(er(n, !0, !0)) })); function Hr(n) { for (var r = n && Nr(n, Y).length || 0, t = Array(r), e = 0; e < r; e++)t[e] = Br(n, e); return t } var Qr = j(Hr); function Xr(n, r) { return n._chain ? tn(r).chain() : r } function Yr(n) { return mr(wn(n), (function (r) { var t = tn[r] = n[r]; tn.prototype[r] = function () { var n = [this._wrapped]; return o.apply(n, arguments), Xr(this, t.apply(tn, n)) } })), tn } mr(["pop", "push", "reverse", "shift", "sort", "splice", "unshift"], (function (n) { var r = t[n]; tn.prototype[n] = function () { var t = this._wrapped; return null != t && (r.apply(t, arguments), "shift" !== n && "splice" !== n || 0 !== t.length || delete t[0]), Xr(this, t) } })), mr(["concat", "join", "slice"], (function (n) { var r = t[n]; tn.prototype[n] = function () { var n = this._wrapped; return null != n && (n = r.apply(n, arguments)), Xr(this, n) } })); var Zr = Yr({ __proto__: null, VERSION: n, restArguments: j, isObject: _, isNull: function (n) { return null === n }, isUndefined: w, isBoolean: A, isElement: function (n) { return !(!n || 1 !== n.nodeType) }, isString: S, isNumber: O, isDate: M, isRegExp: E, isError: B, isSymbol: N, isArrayBuffer: I, isDataView: q, isArray: U, isFunction: D, isArguments: L, isFinite: function (n) { return !N(n) && d(n) && !isNaN(parseFloat(n)) }, isNaN: $, isTypedArray: X, isEmpty: function (n) { if (null == n) return !0; var r = Y(n); return "number" == typeof r && (U(n) || S(n) || L(n)) ? 0 === r : 0 === Y(nn(n)) }, isMatch: rn, isEqual: function (n, r) { return on(n, r) }, isMap: dn, isWeakMap: gn, isSet: bn, isWeakSet: mn, keys: nn, allKeys: an, values: jn, pairs: function (n) { for (var r = nn(n), t = r.length, e = Array(t), u = 0; u < t; u++)e[u] = [r[u], n[r[u]]]; return e }, invert: _n, functions: wn, methods: wn, extend: xn, extendOwn: Sn, assign: Sn, defaults: On, create: function (n, r) { var t = Mn(n); return r && Sn(t, r), t }, clone: function (n) { return _(n) ? U(n) ? n.slice() : xn({}, n) : n }, tap: function (n, r) { return r(n), n }, get: In, has: function (n, r) { for (var t = (r = Bn(r)).length, e = 0; e < t; e++) { var u = r[e]; if (!W(n, u)) return !1; n = n[u] } return !!t }, mapObject: function (n, r, t) { r = Pn(r, t); for (var e = nn(n), u = e.length, o = {}, i = 0; i < u; i++) { var a = e[i]; o[a] = r(n[a], a, n) } return o }, identity: Tn, constant: C, noop: qn, toPath: En, property: Dn, propertyOf: function (n) { return null == n ? qn : function (r) { return In(n, r) } }, matcher: kn, matches: kn, times: function (n, r, t) { var e = Array(Math.max(0, n)); r = Rn(r, t, 1); for (var u = 0; u < n; u++)e[u] = r(u); return e }, random: Un, now: Wn, escape: $n, unescape: Cn, templateSettings: Kn, template: function (n, r, t) { !r && t && (r = t), r = On({}, r, tn.templateSettings); var e = RegExp([(r.escape || Jn).source, (r.interpolate || Jn).source, (r.evaluate || Jn).source].join("|") + "|$", "g"), u = 0, o = "__p+='"; n.replace(e, (function (r, t, e, i, a) { return o += n.slice(u, a).replace(Hn, Qn), u = a + r.length, t ? o += "'+\n((__t=(" + t + "))==null?'':_.escape(__t))+\n'" : e ? o += "'+\n((__t=(" + e + "))==null?'':__t)+\n'" : i && (o += "';\n" + i + "\n__p+='"), r })), o += "';\n"; var i, a = r.variable; if (a) { if (!Xn.test(a)) throw new Error("variable is not a bare identifier: " + a) } else o = "with(obj||{}){\n" + o + "}\n", a = "obj"; o = "var __t,__p='',__j=Array.prototype.join," + "print=function(){__p+=__j.call(arguments,'');};\n" + o + "return __p;\n"; try { i = new Function(a, "_", o) } catch (n) { throw n.source = o, n } var f = function (n) { return i.call(this, n, tn) }; return f.source = "function(" + a + "){\n" + o + "}", f }, result: function (n, r, t) { var e = (r = Bn(r)).length; if (!e) return D(t) ? t.call(n) : t; for (var u = 0; u < e; u++) { var o = null == n ? void 0 : n[r[u]]; void 0 === o && (o = t, u = e), n = D(o) ? o.call(n) : o } return n }, uniqueId: function (n) { var r = ++Yn + ""; return n ? n + r : r }, chain: function (n) { var r = tn(n); return r._chain = !0, r }, iteratee: Vn, partial: nr, bind: rr, bindAll: ur, memoize: function (n, r) { var t = function (e) { var u = t.cache, o = "" + (r ? r.apply(this, arguments) : e); return W(u, o) || (u[o] = n.apply(this, arguments)), u[o] }; return t.cache = {}, t }, delay: or, defer: ir, throttle: function (n, r, t) { var e, u, o, i, a = 0; t || (t = {}); var f = function () { a = !1 === t.leading ? 0 : Wn(), e = null, i = n.apply(u, o), e || (u = o = null) }, c = function () { var c = Wn(); a || !1 !== t.leading || (a = c); var l = r - (c - a); return u = this, o = arguments, l <= 0 || l > r ? (e && (clearTimeout(e), e = null), a = c, i = n.apply(u, o), e || (u = o = null)) : e || !1 === t.trailing || (e = setTimeout(f, l)), i }; return c.cancel = function () { clearTimeout(e), a = 0, e = u = o = null }, c }, debounce: function (n, r, t) { var e, u, o, i, a, f = function () { var c = Wn() - u; r > c ? e = setTimeout(f, r - c) : (e = null, t || (i = n.apply(a, o)), e || (o = a = null)) }, c = j((function (c) { return a = this, o = c, u = Wn(), e || (e = setTimeout(f, r), t && (i = n.apply(a, o))), i })); return c.cancel = function () { clearTimeout(e), e = o = a = null }, c }, wrap: function (n, r) { return nr(r, n) }, negate: ar, compose: function () { var n = arguments, r = n.length - 1; return function () { for (var t = r, e = n[r].apply(this, arguments); t--;)e = n[t].call(this, e); return e } }, after: function (n, r) { return function () { if (--n < 1) return r.apply(this, arguments) } }, before: fr, once: cr, findKey: lr, findIndex: pr, findLastIndex: vr, sortedIndex: hr, indexOf: dr, lastIndexOf: gr, find: br, detect: br, findWhere: function (n, r) { return br(n, kn(r)) }, each: mr, forEach: mr, map: jr, collect: jr, reduce: wr, foldl: wr, inject: wr, reduceRight: Ar, foldr: Ar, filter: xr, select: xr, reject: function (n, r, t) { return xr(n, ar(Pn(r)), t) }, every: Sr, all: Sr, some: Or, any: Or, contains: Mr, includes: Mr, include: Mr, invoke: Er, pluck: Br, where: function (n, r) { return xr(n, kn(r)) }, max: Nr, min: function (n, r, t) { var e, u, o = 1 / 0, i = 1 / 0; if (null == r || "number" == typeof r && "object" != typeof n[0] && null != n) for (var a = 0, f = (n = tr(n) ? n : jn(n)).length; a < f; a++)null != (e = n[a]) && e < o && (o = e); else r = Pn(r, t), mr(n, (function (n, t, e) { ((u = r(n, t, e)) < i || u === 1 / 0 && o === 1 / 0) && (o = n, i = u) })); return o }, shuffle: function (n) { return kr(n, 1 / 0) }, sample: kr, sortBy: function (n, r, t) { var e = 0; return r = Pn(r, t), Br(jr(n, (function (n, t, u) { return { value: n, index: e++, criteria: r(n, t, u) } })).sort((function (n, r) { var t = n.criteria, e = r.criteria; if (t !== e) { if (t > e || void 0 === t) return 1; if (t < e || void 0 === e) return -1 } return n.index - r.index })), "value") }, groupBy: Rr, indexBy: Fr, countBy: Vr, partition: Pr, toArray: Tr, size: function (n) { return null == n ? 0 : tr(n) ? n.length : nn(n).length }, pick: Ur, omit: Wr, first: Lr, head: Lr, take: Lr, initial: zr, last: function (n, r, t) { return null == n || n.length < 1 ? null == r || t ? void 0 : [] : null == r || t ? n[n.length - 1] : $r(n, Math.max(0, n.length - r)) }, rest: $r, tail: $r, drop: $r, compact: function (n) { return xr(n, Boolean) }, flatten: function (n, r) { return er(n, r, !1) }, without: Kr, uniq: Jr, unique: Jr, union: Gr, intersection: function (n) { for (var r = [], t = arguments.length, e = 0, u = Y(n); e < u; e++) { var o = n[e]; if (!Mr(r, o)) { var i; for (i = 1; i < t && Mr(arguments[i], o); i++); i === t && r.push(o) } } return r }, difference: Cr, unzip: Hr, transpose: Hr, zip: Qr, object: function (n, r) { for (var t = {}, e = 0, u = Y(n); e < u; e++)r ? t[n[e]] = r[e] : t[n[e][0]] = n[e][1]; return t }, range: function (n, r, t) { null == r && (r = n || 0, n = 0), t || (t = r < n ? -1 : 1); for (var e = Math.max(Math.ceil((r - n) / t), 0), u = Array(e), o = 0; o < e; o++, n += t)u[o] = n; return u }, chunk: function (n, r) { if (null == r || r < 1) return []; for (var t = [], e = 0, u = n.length; e < u;)t.push(i.call(n, e, e += r)); return t }, mixin: Yr, default: tn }); return Zr._ = Zr, Zr
  7. }));
<input type="text">
  1. <!--本地引入:下载js文件.并且版本引入-->
  2. <script src="./js/underscore.js"></script>
  3. let counter = 1
  4. inputEl.oninput = _.debounce(function(){
  5. console.log(`发送网络请求${counter++}:`,this.value)
  6. },500)

 3.手写防抖(初步实现)

基本实现手写防抖函数。

<input type="text">
  1. <script>
  2. function jydebounce(fn, delay) {
  3. let timer = null; // 定义一个定时器变量,用于存储 setTimeout 返回的计时器 ID
  4. const _debounce = () => {
  5. // 每次调用 _debounce 函数时,先清除之前的定时器
  6. if (timer) clearTimeout(timer)
  7. // 创建一个新的定时器,延迟执行传入的函数 fn
  8. timer = setTimeout(() => {
  9. fn()
  10. timer = null //执行过函数之后,将timer重新置为null
  11. }, delay);
  12. }
  13. //返回一个新的函数
  14. return _debounce
  15. }
  16. </script>
  17. <script>
  18. //1.获取input的元素
  19. const inputEl = document.querySelector("input")
  20. //2.手写防抖
  21. let counter = 1
  22. inputEl.oninput = jydebounce(function () {
  23. console.log(`发送网络请求${counter++}:`, this.value)
  24. }, 500)
  25. </script>

 4.手写防抖(高级实现)

内含立即执行功能,取消功能。

  1. <input type="text">
  2. <button class="cancel">取消</button>
  1. //原则:一个函数进行做一件事情,一个变量也用于记录一种状态
  2. function jydebounce(fn, delay, immediate = false) {
  3. // 1.用于记录上一次事件触发的timer
  4. let timer = null;
  5. let isInvoke = false
  6. // 2.触发事件时执行的函数
  7. const _debounce = function (...args) {
  8. // 2.1.如果有再次触发(更多次触发)事件,那么取消上一次的事件
  9. if (timer) clearTimeout(timer)
  10. // 第一次操作是不需要延迟
  11. if (immediate && !isInvoke) {
  12. fn.apply(this, args)
  13. isInvoke = true
  14. return
  15. }
  16. // 2.2. 延迟去执行的对应的fn函数(传入的回调函数)
  17. timer = setTimeout(() => {
  18. fn.apply(this, args)
  19. timer = null //执行过函数之后,将timer重新置为null
  20. isInvoke = false
  21. }, delay);
  22. }
  23. // 3.给_debounce绑定一个取消的函数
  24. _debounce.cancel = function () {
  25. if (timer) clearTimeout(timer)
  26. timer = null
  27. isInvoke = false
  28. }
  29. //返回一个新的函数
  30. return _debounce
  31. }
  32. //1.获取input的元素
  33. const inputEl = document.querySelector("input")
  34. const cancelBtn = document.querySelector(".cancel")
  35. //2.手写防抖
  36. let counter = 1
  37. const debounceFn = jydebounce(function (event) {
  38. console.log(`发送网络请求${counter++}:`, this, event)
  39. }, 100)
  40. inputEl.oninput = debounceFn
  41. //3.实现取消的功能
  42. cancelBtn.onclick = function () {
  43. debounceFn.cancel()
  44. }

5.实现防抖-获取返回值

  1. <button>按钮</button>
  2. <input type="text">
  3. <button class="cancel">取消</button>

  1. //原则:一个函数进行做一件事情,一个变量也用于记录一种状态
  2. function jydebounce(fn, delay, immediate = false, resultCallback) {
  3. // 1.用于记录上一次事件触发的timer
  4. let timer = null;
  5. let isInvoke = false
  6. // 2.触发事件时执行的函数
  7. const _debounce = function (...args) {
  8. return new Promise((resolve, reject) => {
  9. try {
  10. // 2.1.如果有再次触发(更多次触发)事件,那么取消上一次的事件
  11. if (timer) clearTimeout(timer)
  12. // 第一次操作是不需要延迟
  13. let res = undefined
  14. if (immediate && !isInvoke) {
  15. res = fn.apply(this, args)
  16. if (resultCallback) resultCallback(res)
  17. resolve(res)
  18. isInvoke = true
  19. return
  20. }
  21. // 2.2. 延迟去执行的对应的fn函数(传入的回调函数)
  22. timer = setTimeout(() => {
  23. res = fn.apply(this, args)
  24. if (resultCallback) resultCallback(res)
  25. resolve(res)
  26. timer = null //执行过函数之后,将timer重新置为null
  27. isInvoke = false
  28. }, delay);
  29. } catch (error) {
  30. reject(error)
  31. }
  32. })
  33. }
  34. // 3.给_debounce绑定一个取消的函数
  35. _debounce.cancel = function () {
  36. if (timer) clearTimeout(timer)
  37. timer = null
  38. isInvoke = false
  39. }
  40. //返回一个新的函数
  41. return _debounce
  42. }
  43. //1.获取input的元素
  44. const inputEl = document.querySelector("input")
  45. const cancelBtn = document.querySelector(".cancel")
  46. // 2.手动绑定函数和执行
  47. const myDebounceFn = jydebounce(function (name, age, height) {
  48. console.log("-------- ", name, age, height)
  49. return "哈哈哈哈"
  50. }, 1000, false)
  51. myDebounceFn("xx", 19, 1.99).then(res => {
  52. console.log("拿到执行结果:", res)
  53. })

三、防抖函数的应用

  • 输入框输入联想搜索:用户在输入框中连续输入字符时,只在用户输入完成后一段时间内进行搜索,而不是在每次输入时都进行搜索,从而减少不必要的网络请求和搜索结果的更新频率。
  • 按钮点击事件:在用户点击按钮时执行一些操作,但如果用户连续点击同一个按钮多次,只在最后一次点击后执行操作,避免多次点击造成的重复操作或界面跳转。
  • 浏览器窗口resize事件:当用户调整浏览器窗口大小时触发resize事件,使用函数防抖可以确保只在用户停止调整窗口大小后执行相应的操作,例如重新布局页面或重新计算元素尺寸。

四、最终实现函数封装

  1. //原则:一个函数进行做一件事情,一个变量也用于记录一种状态
  2. function jydebounce(fn, delay, immediate = false, resultCallback) {
  3. // 1.用于记录上一次事件触发的timer
  4. let timer = null;
  5. let isInvoke = false
  6. // 2.触发事件时执行的函数
  7. const _debounce = function (...args) {
  8. return new Promise((resolve, reject) => {
  9. try {
  10. // 2.1.如果有再次触发(更多次触发)事件,那么取消上一次的事件
  11. if (timer) clearTimeout(timer)
  12. // 第一次操作是不需要延迟
  13. let res = undefined
  14. if (immediate && !isInvoke) {
  15. res = fn.apply(this, args)
  16. if (resultCallback) resultCallback(res)
  17. resolve(res)
  18. isInvoke = true
  19. return
  20. }
  21. // 2.2. 延迟去执行的对应的fn函数(传入的回调函数)
  22. timer = setTimeout(() => {
  23. res = fn.apply(this, args)
  24. if (resultCallback) resultCallback(res)
  25. resolve(res)
  26. timer = null //执行过函数之后,将timer重新置为null
  27. isInvoke = false
  28. }, delay);
  29. } catch (error) {
  30. reject(error)
  31. }
  32. })
  33. }
  34. // 3.给_debounce绑定一个取消的函数
  35. _debounce.cancel = function () {
  36. if (timer) clearTimeout(timer)
  37. timer = null
  38. isInvoke = false
  39. }
  40. //返回一个新的函数
  41. return _debounce
  42. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/565767
推荐阅读
相关标签
  

闽ICP备14008679号