Использование Vue для защиты от тряски и дросселирования

Vue.js

Сцены

В проекте фильма я хочу сохранить текущую позицию раскрывающегося списка в списке фильмов, чтобы вы не могли переключать страницы, а затем возвращаться на текущую страницу списка фильмов, он вернется к первым данным фильм.
В настоящее время я не хочу сохранять текущую позицию каждый раз, когда я просто немного смахиваю, я хочу сохранять ее время от времени.В настоящее время я могу использовать анти-дрожание и дросселирование.

концепция

если быть честным,Дроссельная защита от сотрясений заключается в использовании таймера.для достижения нашей цели.

Что касается использования таймера, пожалуйста, перейдите к:Использование обычных таймеров в 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)
        }
    }
}

V_V