1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
|
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta name="author" content="韩暮秋">
<meta name="subtitle" content="暮秋小屋">
<meta name="description" content="这里是暮秋小屋,思念和灵感的寄存处">
<meta name="keywords" content="韩暮秋,MuqiuHan,'Muqiu Han', 'muqiu han', muqiuhan">
<title>实时搜索中的防抖函数 | 暮秋小屋</title>
<link rel="icon" href="/favicon.ico">
<style>
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&family=Roboto+Mono&display=swap');
</style>
<!-- stylesheets list from _config.yml -->
<link rel="stylesheet" href="/css/style.css">
<!-- scripts list from _config.yml -->
<script src="/js/frame.js"></script>
<script src="https://polyfill.alicdn.com/polyfill.js?features=es6"></script>
<script id="MathJax-script" async src="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/mathjax/3.2.0/es5/tex-mml-chtml.js"></script>
<meta name="generator" content="Hexo 6.3.0"></head>
<body>
<div class="mask-border">
</div>
<div class="wrapper">
<div class="header">
<div class="flex-container">
<div class="header-inner">
<div class="site-brand-container">
<a href="/">
暮秋小屋
</a>
</div>
<div id="menu-btn" class="menu-btn" onclick="toggleMenu()">
Menu
</div>
<nav class="site-nav">
<ul class="menu-list">
<li class="menu-item">
<a href="/">主页</a>
</li>
<li class="menu-item">
<a href="/categories/gallery/">日记本</a>
</li>
<li class="menu-item">
<a href="/tags/Medicine/">医学</a>
</li>
<li class="menu-item">
<a href="/tags/Technique/">计算机科学</a>
</li>
<li class="menu-item">
<a href="/tags/Life/">生活</a>
</li>
<li class="menu-item">
<a href="/about">关于</a>
</li>
<li class="menu-item search-btn">
<a href="#">Search</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<script src="/js/menu.js"></script>
<div class="main">
<div class="flex-container">
<article id="post">
<div class="post-head">
<div class="post-info">
<div class="tag-list">
<span class="post-tag">
<a href="/tags/Technique/">
Technique
</a>
</span>
<span class="post-tag">
<a href="/tags/Web/">
Web
</a>
</span>
</div>
<div class="post-title">
实时搜索中的防抖函数
</div>
<span class="post-date">
Feb 10, 2025
</span>
</div>
<div class="post-img">
<div class="h-line-primary"></div>
</div>
</div>
<div class="post-content">
<p>在实现实时搜索功能时,通常会使用输入框的事件监听器来捕获用户的输入变化,并在输入变化时发送搜索请求。为了避免过多的请求导致服务器负担过重,通常会使用“防抖”(debounce)技术来控制请求的频率。</p>
<h3 id="实现步骤"><a href="#实现步骤" class="headerlink" title="实现步骤"></a>实现步骤</h3><ol>
<li><strong>监听输入框的变化</strong>:使用<code>input</code>事件监听器来捕获用户的输入变化。</li>
<li><strong>防抖处理</strong>:使用防抖函数来限制请求的频率。防抖函数会在用户停止输入一段时间后才发送请求。</li>
<li><strong>发送请求</strong>:在防抖函数中调用搜索请求。</li>
</ol>
<h3 id="防抖函数示例"><a href="#防抖函数示例" class="headerlink" title="防抖函数示例"></a>防抖函数示例</h3><p>以下是一个简单的防抖函数示例:</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">function</span> <span class="title function_">debounce</span>(<span class="params">func, wait</span>) {</span><br><span class="line"> <span class="keyword">let</span> timeout;</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">function</span>(<span class="params">...args</span>) {</span><br><span class="line"> <span class="keyword">const</span> context = <span class="variable language_">this</span>;</span><br><span class="line"> <span class="built_in">clearTimeout</span>(timeout);</span><br><span class="line"> timeout = <span class="built_in">setTimeout</span>(<span class="function">() =></span> func.<span class="title function_">apply</span>(context, args), wait);</span><br><span class="line"> };</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h3 id="实现实时搜索"><a href="#实现实时搜索" class="headerlink" title="实现实时搜索"></a>实现实时搜索</h3><p>假设你有一个输入框用于搜索患者:</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><script></span><br><span class="line"> import { onMount } from 'svelte';</span><br><span class="line"> import { patientsStore } from '$lib/stores/patients.svelte';</span><br><span class="line"></span><br><span class="line"> let searchTerm = '';</span><br><span class="line"></span><br><span class="line"> // 防抖函数</span><br><span class="line"> function debounce(func, wait) {</span><br><span class="line"> let timeout;</span><br><span class="line"> return function(...args) {</span><br><span class="line"> const context = this;</span><br><span class="line"> clearTimeout(timeout);</span><br><span class="line"> timeout = setTimeout(() => func.apply(context, args), wait);</span><br><span class="line"> };</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> // 搜索函数</span><br><span class="line"> const searchPatients = debounce(async (term) => {</span><br><span class="line"> if (term) {</span><br><span class="line"> // 发送搜索请求</span><br><span class="line"> const response = await fetch(`/api/search-patients?query=${term}`);</span><br><span class="line"> const data = await response.json();</span><br><span class="line"> patientsStore.mbglPatients = data;</span><br><span class="line"> } else {</span><br><span class="line"> // 清空搜索结果或恢复默认数据</span><br><span class="line"> patientsStore.mbglPatients = [];</span><br><span class="line"> }</span><br><span class="line"> }, 300); // 300ms 的防抖时间</span><br><span class="line"></span><br><span class="line"> // 监听输入框变化</span><br><span class="line"> function handleInput(event) {</span><br><span class="line"> searchTerm = event.target.value;</span><br><span class="line"> searchPatients(searchTerm);</span><br><span class="line"> }</span><br><span class="line"></script></span><br><span class="line"></span><br><span class="line"><input type="text" placeholder="搜索患者..." on:input={handleInput} bind:value={searchTerm} /></span><br></pre></td></tr></table></figure>
<h3 id="请求发送间隔"><a href="#请求发送间隔" class="headerlink" title="请求发送间隔"></a>请求发送间隔</h3><ul>
<li><strong>防抖时间</strong>:通常设置为 300ms 到 500ms 之间。这个时间足够让用户完成输入并减少不必要的请求。</li>
<li><strong>考虑用户体验</strong>:防抖时间过短可能导致过多请求,过长则可能让用户感到延迟。300ms 是一个常用的折中值。</li>
</ul>
<p>通过这种方式,你可以实现一个高效的实时搜索功能,既能保证用户体验,又能减少服务器的负担。</p>
</div>
<script>
window.onload = detectors();
</script>
<div class="post-footer">
<div class="h-line-primary"></div>
<nav class="post-nav">
<div class="prev-item">
<div class="icon arrow-left"></div>
<div class="post-link">
<a href="/2025/02/11/%E4%BB%8E%E4%BA%8B%E4%BB%B6%E9%A3%8E%E6%9A%B4%E7%9C%8B%E9%A2%86%E5%9F%9F%E9%A9%B1%E5%8A%A8%E8%AE%BE%E8%AE%A1/">Prev</a>
</div>
</div>
<div class="next-item">
<div class="icon arrow-right"></div>
<div class="post-link">
<a href="/2025/01/19/%E8%BA%AB%E4%BD%93%E5%BE%80%E5%89%8D%E5%80%BE%EF%BC%8C%E7%81%B5%E9%AD%82%E5%90%91%E5%90%8E%E6%91%87/">Next</a>
</div>
</div>
</nav>
</div>
<div class="post-comment">
</div>
</article>
</div>
</div>
<div class="footer">
<div class="flex-container">
<div class="footer-text">
|
希望路过的人可以添点柴火让这里暖和点
</div>
</div>
</div>
</div>
<div class="search-popup">
<div class="search-popup-overlay">
</div>
<div class="search-popup-window" >
<div class="search-header">
<div class="search-input-container">
<input autocomplete="off" autocapitalize="off" maxlength="80"
placeholder="Search Anything" spellcheck="false"
type="search" class="search-input">
</div>
<div class="search-close-btn">
<div class="icon close-btn"></div>
</div>
</div>
<div class="search-result-container">
</div>
</div>
</div>
<script>
const searchConfig = {
path : "/search.xml",
top_n_per_article: "1",
unescape : "false",
trigger: "auto",
preload: "false"
}
</script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/search.js"></script>
<script src="/js/search.js"></script>
</body>
</html>
|