>웹 프론트엔드 >JS 튜토리얼 >JavaScript 주제 3: 흔들림 방지

JavaScript 주제 3: 흔들림 방지

coldplay.xixi
coldplay.xixi앞으로
2021-03-04 09:56:003235검색

JavaScript 주제 3: 흔들림 방지

목차

  • 1. 흔들림 방지가 필요한 이유
  • 2. 흔들림 방지의 원리
  • 3. shake
  • 마지막에 작성
(관련 무료학습 추천 :

javascript video tutorial)

1. 흔들림 방지가 필요한 이유

High- 주파수 함수 연산 resize, scroll, mousedown, mousemove, keyup, keydown...
  • 이를 위해 이벤트가 자주 트리거되는 방식을 이해하기 위한 샘플 코드를 제공합니다.
  • 색인을 작성합니다. .html 파일:
    <meta>
    <meta>
    <meta>
    <title>Document</title>
    <title>debounce</title>
    <style>
        #wrapper {
            width: 100%;
            height: 200px;
            line-height: 200px;
            text-align: center;
            color: #fff;
            background-color: #444;
            font-size: 30px;
        }
    </style>
    <p></p>
    <script>
        var count = 1;
        var op = document.getElementById("wrapper");

        function getUserAction() {
            op.innerHTML = count++;
        }

        op.onmousemove = getUserAction;
    </script>

왼쪽에서 오른쪽으로 슬라이드할 때 트리거됨 getUserAction 함수가 거의 100번 사용되었습니다! 다음 Gif를 참조하세요.

여기에 이미지 설명 삽입

이 예는 매우 간단하기 때문에 브라우저가 완벽하게 반응할 수 있지만 다음과 같이 가정합니다. getUserAction 函数!看如下Gif:

JavaScript 주제 3: 흔들림 방지

因为这个例子很简单,所以浏览器完全反应的过来,但假设:

  • 它的触发频次极高,1分钟2000次,且涉及到大量的位置计算、DOM 操作等工作,
  • 存在接口请求,单个函数执行时间较长,但每个函数触发的间隔很近。

这种在一瞬间(短时间内)对浏览器或服务器造成了过多压力的交互就需要进行优化了,为了解决这个问题,一般有两种解决方案:

  • debounce 防抖
  • throttle 节流

他们的目的都是:降低一个函数的触发频率,以提高性能或避免资源浪费。

二、防抖的原理

今天重点讲讲防抖的实现。

防抖的原理就是:你尽管触发事件,但是我一定在事件触发n秒无操作后才执行。举个例子:

我们规定3s为防抖的标准,那么:

  1. 第一次要求执行事件 - 此时倒计时3s
  2. 倒计时2s
  3. 倒计时1s
  4. 0.5s时事件再次被触发 - 此时倒计时3s
  5. …3s内无事发生
  6. 执行事件,共用了5.5s

JavaScript 주제 3: 흔들림 방지

三、自己实现一个防抖

3.1 第一版

我们根据上一节提到的核心思想,实现第一版代码:

function debounce(func, wait) {
    var timer;
    return function () {
        clearTimeout(timer)
        timer = setTimeout(func, wait);
    }}

如果我们要使用它,第一节的例子为例:

op.onmousemove = debounce(getUserAction, 2000);

此时大家可以再次测试一下,事件持续发生时,只有在完全停止2s后,才会触发事件:

写到这里,作为针对部分高频事件的需求来说,已经结束了。我们来看看他的效果:

JavaScript 주제 3: 흔들림 방지

3.2 第二版

大家都知道,dom节点在触发事件的时候,this指向它本身,本例中则指向op,但是在本例中:我们看一下

var count = 1;var op = document.getElementById("op");function getUserAction() {
    op.innerHTML = count++;
    console.log('this', this); // 此时输出 Window...}op.onmousemove = debounce(getUserAction, 2000);function debounce(func, wait) {
    var timer;
    return function () {
        clearTimeout(timer)
        timer = setTimeout(func, wait);
    }}

毕竟经过了一层匿名函数的包裹,this已经指向了window,为了减少影响,我们尝试修正它

function debounce(func, wait) {
    var timer;
    return function () {
        var _this = this; // 记录当前this

        clearTimeout(timer)
        timer = setTimeout(function(){
            func.apply(_this); //将 func的this改为_this
        }, wait);
    }}

第三版

解决的this指向问题,我们的函数仍然不够“完美”,JavaScript中,事件处理函数会提供event对象,我们简称为e。

// 使用了 debouce 函数function getUserAction(e) {
    console.log(e); // undefined
    op.innerHTML = count++;};

为了保证它的原汁原味,我们再改第三版:

var count = 1;var op = document.getElementById("op");function getUserAction(e) {
    op.innerHTML = count++;
    console.log('e', e); // MouseEvent}op.onmousemove = debounce(getUserAction, 2000);function debounce(func, wait) {
    var timer;
    return function () {
        var _this = this; // 记录当前this
        var arg = arguments; // 记录参数
        clearTimeout(timer)
        timer = setTimeout(function () {
            func.apply(_this, arg); //将 func的this改为_this
        }, wait);
    }}

到此为止,我们在尽可能保留Dom事件原有能力的情况下,给函数加上了防抖效果,它可以解决大部分我们日常开发的防抖问题,但我们需要更“完美”

JavaScript 주제 3: 흔들림 방지

四、防抖进阶

4.1 立即执行

这个需求就是:

  • 立即执行
  • 保持n秒空白期
  • n秒空白期置后

想想这个需求也是很有道理的嘛,那我们加个immediate

분당 2000번으로 매우 자주 트리거되고 위치 계산, DOM 작업 등이 많이 포함됩니다.

인터페이스 요청이 있습니다. 단일 함수는 실행하는 데 오랜 시간이 걸리지만 각 함수는 매우 가까운 간격으로 트리거됩니다. JavaScript 주제 3: 흔들림 방지

단시간에 브라우저나 서버에 너무 많은 부담을 주는 이러한 상호 작용은 최적화되어야 합니다. 이 문제를 해결하려면 일반적으로 두 가지 솔루션이 있습니다:

debounce anti-shake

throttle Throttling.

목적은 다음과 같습니다. JavaScript 주제 3: 흔들림 방지기능의 트리거 빈도를 줄여 성능을 향상하거나 리소스 낭비를 방지합니다.

🎜 2. 손떨림 방지의 원리 🎜🎜🎜 오늘은 손떨림 방지 구현에 대해 집중적으로 살펴보겠습니다. 🎜🎜흔들림 방지의 원리는 이벤트를 트리거하더라도 이벤트가 트리거된 후 n초 동안 활동이 없으면 후에만 실행한다는 것입니다. 예: 🎜🎜3s가 손떨림 방지의 표준이라고 규정한 경우: 🎜
    🎜처음 이벤트가 요청될 때 - 현재 카운트다운은 3초입니다🎜🎜카운트다운 2초🎜🎜카운트다운은 1초입니다🎜🎜 0.5초에 이벤트가 다시 발생합니다. 이때 카운트다운은 3초입니다🎜🎜... 3초 이내에 아무 일도 일어나지 않습니다🎜🎜실행 이벤트에 5.5초가 걸립니다🎜
JavaScript 주제 3: 흔들림 방지🎜🎜🎜셋. 손떨림 방지 구현🎜🎜🎜3.1 첫 번째 버전🎜🎜이전 섹션에서 언급한 핵심 아이디어를 기반으로 첫 번째 버전의 코드를 구현했습니다.🎜
function debounce(func, wait, immediate) {
    var timer;

    return function () {
        var _this = this;
        var args = arguments;

        if (timer) clearTimeout(timer); // 常规流程,间隔内触发时清掉重置定时
        if (immediate) {
            // 如果已经执行过,不再执行
            var callNow = !timer; // 1. callNow 初始值是 true, 同步立即执行;随后 timer 才开始执行
            timer = setTimeout(function(){
                timer = null; // wait 期间,timer 是一个 ID 数字,所以 callNow 为 false,func 在此期间永远不会执行
            }, wait) // wait 之后,timer 赋值 null,callNow 为 true,func 又开始立即执行。
            if (callNow) func.apply(_this, args)
        }
        else {
            timer = setTimeout(function(){
                func.apply(_this, args)
            }, wait);
        }
    }}
🎜사용하려면, 첫 번째 섹션의 예를 예로 들어 보겠습니다. 🎜
function debounce(func, wait, immediate) {
    var timer;
    // 检查函数
    if (typeof func !== 'function') {
        throw new TypeError('Expected a function');
    }
    // 保证wait存在
    wait = +wait || 0;

    const debounced = function () {
        var _this = this;
        var args = arguments;

        if (timer) clearTimeout(timer); // 常规流程,间隔内触发时清掉重置定时
        if (immediate) {
            // 如果已经执行过,不再执行
            var callNow = !timer; // 如果不存在定时器,则callNow为true
            timer = setTimeout(function () {
                timer = null; // 为了保证之后的时效性,手动添加timer
            }, wait)
            // 因为不存在timer,证明是首次执行,所以直接调用
            if (callNow) func.apply(_this, args)
        }
        else {
            timer = setTimeout(function () {
                func.apply(_this, args)
            }, wait);
        }
    }
    return debounced}
🎜 이때 다시 테스트할 수 있습니다. 이벤트가 계속 발생하면 완전히 정지한 후 2초 후에만 이벤트가 트리거됩니다. 🎜🎜여기에 다음과 같이 작성했습니다. 일부 고주파 이벤트에 대한 요구 사항은 끝났습니다. 그 효과를 살펴보겠습니다. 🎜🎜여기에 이미지 설명 삽입🎜🎜3.2 Second Edition🎜🎜dom 노드가 이벤트를 트리거할 때 this가 자신을 가리킨다는 것은 누구나 알고 있지만, 이 경우에는 살펴보겠습니다 🎜
function debounce(func, wait, immediate) {
    var timer;
    // 检查函数
    if (typeof func !== 'function') {
        throw new TypeError('Expected a function');
    }
    // 保证wait存在
    wait = +wait || 0;

    const debounced = function () {
        var _this = this;
        var args = arguments;

        if (timer) clearTimeout(timer); // 常规流程,间隔内触发时清掉重置定时
        if (immediate) {
            // 如果已经执行过,不再执行
            var callNow = !timer; // 如果不存在定时器,则callNow为true
            timer = setTimeout(function () {
                timer = null; // 为了保证之后的时效性,手动添加timer
            }, wait)
            // 因为不存在timer,证明是首次执行,所以直接调用
            if (callNow) func.apply(_this, args)
        }
        else {
            timer = setTimeout(function () {
                func.apply(_this, args)
            }, wait);
        }
    }

    const cancel = function(){
        clearTimeout(timer);
        timer = null;
    }

    const pending = function(){
        return timer !== undefined;
    }

    debounced.cancel = cancel;
    debounced.pending = pending;
    return debounced}
🎜결국 이것은 익명 함수로 래핑된 후 영향을 줄이기 위해 이를 수정하려고 합니다. 🎜rrreee🎜제3판🎜🎜우리 함수는 다음과 같습니다. 아직 충분히 "완벽"하지는 않습니다. JavaScript에서 이벤트 처리 함수는 줄여서 e라고 부르는 event 객체를 제공합니다. 🎜rrreee🎜진위성을 보장하기 위해 세 번째 버전을 변경합니다: 🎜rrreee🎜지금까지는 Dom 이벤트의 원래 기능을 최대한 유지하면서 기능에 흔들림 방지 효과를 추가할 수 있습니다. 일상적인 개발 흔들림 방지 문제의 대부분을 해결하지만 더 "완벽"해야 합니다🎜

JavaScript 주제 3: 흔들림 방지🎜🎜🎜 4. 흔들림 방지 고급 🎜🎜🎜4.1 즉시 실행 🎜🎜이 요구 사항은 다음과 같습니다. 즉시 실행 🎜 🎜두 번째 공백 기간을 n으로 유지🎜🎜두 번째 공백 기간을 n 뒤에 두세요🎜🎜🎜이 요구 사항을 생각한 다음 immediate 매개변수는 즉시 실행 여부를 결정합니다. 🎜rrreee🎜이번에 그 효과를 살펴보겠습니다. 🎜🎜🎜🎜🎜4.2 간편 인증 추가🎜rrreee🎜4.3 취소 이벤트 방식 추가🎜🎜흔들림 방지 이벤트를 취소하려면 다음과 같이 쓰면 됩니다. 🎜rrreee 🎜효과를 살펴보겠습니다. 🎜🎜🎜🎜🎜 이 간단한 흔들림 방지 방법이 괜찮더라도 실제로는 완벽하지는 않습니다. 개선 사항이 있으면 댓글란에 메시지를 남겨주세요~ 🎜<blockquote><p><strong>관련 무료 학습 권장 사항: </strong><a href="https://www.php.cn/course/list/17.html" target="_blank" textvalue="javascript"><strong>javascript</strong></a><strong>(동영상)</strong></p></blockquote>

위 내용은 JavaScript 주제 3: 흔들림 방지의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 csdn.net에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제