Сцены
В проекте фильма я хочу сохранить текущую позицию раскрывающегося списка в списке фильмов, чтобы вы не могли переключать страницы, а затем возвращаться на текущую страницу списка фильмов, он вернется к первым данным фильм.
В настоящее время я не хочу сохранять текущую позицию каждый раз, когда я просто немного смахиваю, я хочу сохранять ее время от времени.В настоящее время я могу использовать анти-дрожание и дросселирование.
концепция
если быть честным,Дроссельная защита от сотрясений заключается в использовании таймера.для достижения нашей цели.
Что касается использования таймера, пожалуйста, перейдите к:Использование обычных таймеров в JS
Отказаться:
Обратный вызов выполняется через n секунд после запуска события, и если он снова запускается в течение этих n секунд, таймер переустанавливается.
Типичным случаем является поиск в поле ввода: запрос на поиск будет сделан через n секунд после завершения ввода, и время будет пересчитано, если содержимое будет введено снова в течение n секунд.
Дросселирование:
Предусмотрено, что функция может срабатывать только один раз в единицу времени, если функция срабатывает несколько раз в эту единицу времени, сработает только один раз.
Типичным случаем является непрерывный щелчок мышью для запуска, и предусмотрено, что несколько щелчков в течение n секунд сработают только один раз.
использование
Отказаться
Раскрывающийся список, сохраняйте текущую позицию раскрывающегося списка с интервалами.
мы можемmountedРеализуйте наш антишейк в хуке:
// 防抖 定时器
let timer;
//list就是电影列表 ref="list" $el获取DOM元素
this.$refs.list.$el.addEventListener("scroll", e => {
console.log("---->",e.target.scrollTop) //不使用防抖
if (timer) {
//清空timer
clearTimeout(timer);
}
timer = setTimeout(() => {
console.log(e.target.scrollTop) //使用防抖
//在sessionStorage中保存当前下拉位置
// sessionStorage.setItem("position", e.target.scrollTop);
}, 75); //75ms为最佳
});
Демонстрация эффекта(сохранять текущую позицию с интервалами):
добавлять---->Чтобы не использовать анти-встряску, если нет, используйте анти-встряску
Поиск в поле ввода для выполнения поисковых запросов через определенные промежутки времени:
<template>
<div>
<input type="text" @keyup="debounce" />
</div>
</template>
<script>
//定义 timer
let timer;
export default {
methods: {
debounce: function() {
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(() => {
console.log("防抖...");
timer = undefined;
}, 2000);
}
}
};
</script>
дроссель
Нажмите несколько раз в течение n секунд, только один раз вступит в силу.
<template>
<div>
<button @click="throttle">按钮</button>
</div>
</template>
<script>
//定义
let timer, lastTime;
let now = +new Date();
export default {
methods: {
throttle: () => {
if (lastTime && now - lastTime < 200) {
clearTimeout(timer);
console.log("....");
timer = setTimeout(() => {
console.log("点击...");
lastTime = +new Date();
}, 2000);
} else {
lastTime = now;
timer = setTimeout(() => {
console.log("点击...");
lastTime = +new Date();
}, 200);
}
}
}
};
</script>
Демонстрация эффекта:
Пополнить
Конечно, эти два метода также могут быть инкапсулированы для использования в нескольких местах.
// 防抖(在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时)
function debounce(fn, delay) {
let t = delay || 500
let timer
return function() {
clearTimeout(timer)
timer = setTimeout(() => {
// 改变this指向并传递参数
fn.apply(this, arguments)
}, t)
}
}
// 节流(规定在一个单位时间内,只能触发一次函数,如果这个单位时间内触发多次函数,只有一次生效)
function throttle(fn, delay) {
let t = delay || 500
let timer
return function() {
if (!timer) {
timer = setTimeout(() => {
// 为了方便下次执行定时器
timer = null
fn.apply(this, arguments)
}, t)
}
}
}