在Web开发中,我们经常需要对用户的操作进行响应,比如防止用户频繁点击按钮或滚动页面。而JavaScript中通过防抖和节流两种方式来解决这个问题。防抖和节流的核心思想都是通过控制函数的执行次数来达到节省性能的效果,但两者的实现方式略有不同。
防抖的原理是将多次执行变成最后一次执行,也就是在用户停止操作一段时间后才会开始执行相应的函数。这样可以避免短时间内重复触发函数,导致资源浪费。常见应用场景包括:
在这个示例中,我们通过防抖的方式来实现输入框搜索功能,当用户在5秒内连续输入时不会触发搜索,只有在5秒之后没有输入时才会触发搜索操作。
// 防抖函数,func为要执行的函数,delay为等待计时时间
function debounce(func, delay) {
let timer
return function() {
clearTimeout(timer)
timer = setTimeout(() => {
func.apply(this, arguments)
}, delay)
}
}
// 输入框实时搜索示例
const input = document.querySelector('#search')
const search = query => console.log(`Search with query: ${query}`)
input.addEventListener('input', debounce(function() {
search(this.value)
}, 5000))
在这个示例中,我们通过防抖的方式来实现滚动页面时导航栏自动隐藏和显示的效果,在用户连续滚动时不会频繁触发事件,只有在停止滚动一段时间后才会触发事件。
// 导航栏自动隐藏和显示示例
const navbar = document.querySelector('#navbar')
let prevScrollPos = window.pageYOffset
window.addEventListener('scroll', debounce(function() {
const currentScrollPos = window.pageYOffset
if (prevScrollPos > currentScrollPos) {
navbar.style.top = "0"
} else {
navbar.style.top = "-50px"
}
prevScrollPos = currentScrollPos
}, 100))
节流的原理是将多次执行变成每隔一段时间执行一次,也就是当一个函数正在被执行时,不管执行多少次,只在规定的时间间隔内执行一次。常见应用场景包括:
在这个示例中,我们通过节流的方式来实现滚动页面时图片的懒加载,当用户滚动到一定位置时,才会加载对应的图片。节流的时间间隔为100ms,每100ms才会触发一次滚动事件。
// 懒加载图片示例
const images = document.querySelectorAll('img[data-src]')
function lazyLoad() {
const scrollTop = window.pageYOffset
const windowHeight = window.innerHeight
images.forEach(image => {
const top = image.getBoundingClientRect().top
const src = image.getAttribute('data-src')
if (top < windowHeight && top > 0) {
image.setAttribute('src', src)
image.removeAttribute('data-src')
}
})
}
window.addEventListener('scroll', throttle(lazyLoad, 100))
在这个示例中,我们通过节流的方式来监听窗口大小改变事件,每隔500ms执行一次函数,避免频繁触发window.resize事件。
// 监听窗口大小改变事件示例
function handleResize() {
console.log(`Window width: ${window.innerWidth}, height: ${window.innerHeight}`)
}
window.addEventListener('resize', throttle(handleResize, 500))
以上就是JavaScript防抖和节流的详解,防抖和节流的实现方式各有不同,开发者根据具体需求选择合适的方法可以提升页面性能,优化用户体验。
本文链接:http://task.lmcjl.com/news/9352.html