JavaScript 实现带有防抖的搜索框
防抖是一种优化技术,用于限制执行某个任务的次数。例如,在电子商务网站中,当我们在搜索框中搜索某个产品时,可能会发起多次网络调用来获取与该关键字相关的产品列表,防抖就可以用在这种情况下减少网络调用的次数。
问题描述: 首先,我们将展示一个不使用任何防抖技术的搜索框的输出结果。
HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
</head>
<body>
<input />
<div class="result-container"></div>
<script src="src/index.js"></script>
</body>
</html>
CSS
body {
font-family: sans-serif;
}
.item {
margin-top: 10px;
font-family: Cambria, Cochin, Georgia, Times, "Times New Roman", serif;
background-color: ghostwhite;
height: 50px;
color: green;
}
Javascript
import "./styles.css";
const input = document.querySelector("input");
const container = document.querySelector(".result-container");
const makeAPICall = (searchValue) => {
container.innerHTML = "";
if (!searchValue) {
return;
}
// Use the API link to see the result
fetch(`https://api.../v2/beers?beer_name=${searchValue}`)
.then((res) => {
res.json().then((response) => {
console.log(response)
response.forEach((item) => {
const div = document.createElement("div");
div.textContent = item.name;
div.classList.add("item");
container.appendChild(div);
});
});
})
.catch((e) => { });
};
input.addEventListener("input", (e) => {
makeAPICall(e.target.value);
});
输出:
正如我们可以在上面看到的,每输入一个字符就会进行一次API调用,由于这些API调用很昂贵,不建议进行太多的API调用。
现在,我们将看到如何通过使用防抖技术来减少API调用次数。让我们实现一个搜索框,将会减少网络调用。
方法:
- 我们将创建一个 防抖 函数。这个函数将有两个输入,一个是我们希望在输入一些内容时调用的 fn 函数,另一个是延迟 input ,通过这个 input 我们将 延迟 调用 fn 函数。这个 防抖 函数将返回一个函数,这个函数将被存储在一个变量 onInput 中。输入函数 fn 将是一个将通过输入发起后端API调用的函数。这意味着API调用将在用户停止提供输入 delay 毫秒后进行。
- 现在,每当输入一个字符时,我们将调用 onInput 函数。
HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
</head>
<body>
<input />
<div class="result-container"></div>
<script src="src/index.js"></script>
</body>
</html>
CSS
body {
font-family: sans-serif;
}
.item {
margin-top: 10px;
font-family: Cambria, Cochin, Georgia, Times, "Times New Roman", serif;
background-color: ghostwhite;
height: 50px;
color: green;
}
JavaScript
import "./styles.css";
const input = document.querySelector("input");
const container = document.querySelector(".result-container");
const makeAPICall = (searchValue) => {
container.innerHTML = "";
if (!searchValue) {
return;
}
// Use the API link to see the result
fetch(`https://api.../v2/beers?beer_name=${searchValue}`)
.then((res) => {
res.json().then((response) => {
response.forEach((item) => {
const div = document.createElement("div");
div.textContent = item.name;
div.classList.add("item");
container.appendChild(div);
});
});
})
.catch((e) => { });
};
const debounce = (fn, delay = 1000) => {
let timerId = null;
return (...args) => {
clearTimeout(timerId);
timerId = setTimeout(() => fn(...args), delay);
};
};
const onInput = debounce(makeAPICall, 500);
input.addEventListener("input", (e) => {
onInput(e.target.value);
});
输出:
说明: 由于我们使用了去抖技术,因此每次提供输入时API调用不会被执行,而是在停止输入500毫秒后进行API调用。