一般的に使用されるフロントエンド アルゴリズム (1): 手ぶれ補正 + スロットル

目次

第1章 手ぶれ補正

1.1 デバウンスの概要

1.2 応用シナリオ

1.3 実装のアイデア

1.4 ハンドティアリング手ぶれ補正コード

第2章の流れ

2.1 スロットルの概要

2.2 応用シナリオ

2.3 実装のアイデア

2.4 手動スロットル コード (メソッド: タイムスタンプとタイマー)

2.5 タイムスタンプとタイマーの実装の違い

第 3 章の概要


第1章 手ぶれ補正

1.1 デバウンスの概要

  • シナリオ:ユーザーは、一定期間、機能/イベントを実行するために頻繁にクリックします。この期間中、ユーザーが 1 回クリックすると、タイマーの時間が再設定されますユーザーがこの期間中に機能/イベントをトリガーしない場合、機能は/event はこの期間の終了時に実行されます。
  • 応用例の理解:都市への帰還が中断され、プレイヤーは都市への帰還を準備するための残血を持っています。都市への帰還が成功するまでに 3 秒かかります。ただし、この 3 秒のプロセス中に、プレイヤーはクリックします。再び都市に戻ると、3 秒間の都市への戻りが再計算され、さらに 3 秒待機します。

1.2 応用シナリオ

  • ログイン、テキスト メッセージの送信、投稿リクエストの送信などのボタン/イベントにより、ユーザーがクリックしすぎて複数のリクエストを送信することが防止されます。手ぶれ補正が必要で、最後のリクエストを送信できます。
  • ブラウザ ウィンドウのサイズを変更するとき、サイズ変更の回数が多すぎて計算が多すぎます。このとき、一度に行う必要があるため、手ぶれ補正が使用されます。
  • 入力ボックスは文字を入力せずに一度値を取得しますが、手ぶれ補正を使用すると入力完了後に値を取得できます。
  • テキスト エディターはリアルタイムで保存し、変更せずに 1 秒後に保存します。
  • ……

1.3 実装のアイデア

 

1.4 ハンドティアリング手ぶれ補正コード

function debounce(func,delay) {
    // 定义一个定时器timer
    let timer = null
    return function() {
        const that = this
        const args = arguments
        // 防抖核心:每次触发事件计时器都会重新计时
        clearTimeout(timer)
        timer = setTimeout(()=>{
            func.apply(that,args)
        },delay)
    }
}
  • 例:

手ぶれ補正機能が呼び出されない場合:ユーザーが入力に値を入力/削除するたびに、値が出力されます。

    <input type="text" id="input">

    <script>
        let inputDom = document.getElementById('input')
        //获取输入框的输入内容
        inputDom.oninput = function(){
          console.log('this.value',this.value)
        }
    </script>

 

 

手ぶれ補正機能呼び出し後:ユーザーが値の遅延を入力/削除した後にのみ値が出力されます。

    let inputDom = document.getElementById('input')
    //func 是执行函数,delay 是事件执行的延迟时间,毫秒
    function debounce(func,delay) {
        // 定义一个定时器timer
        let timer = null
        return function() {
            const that = this
            const args = arguments
            // 防抖核心:每次触发事件计时器都会重新计时
            clearTimeout(timer)
            timer = setTimeout(()=>{
               func.apply(that,args)
            },delay)
        }
    }
    function handler() {
        console.log('this.value',this.value)
    }
    inputDom.addEventListener('input', debounce(handler, 1000))

第2章の流れ

2.1スロットルの概要

  • シナリオ: ユーザーは、一定期間、関数/イベントを実行するために頻繁にクリックします。この期間中、ユーザーはタイマーの実行に影響を与えることなく 1 回または複数回クリック (イベントの呼び出し) し、関数/イベントは 1 回だけ実行されます。
  • 適用例の理解:スキルのクールダウン中に、プレイヤーは特定の状況下でフラッシュ スキルを使用しましたが、このスキルのクールダウン時間は 120 秒です。この期間中に、プレイヤーは危険に遭遇し、もう一度フラッシュ スキルを使用したいと考えました。頻繁にクリックし、しかしそれは役に立たず、フラッシュは実行されず、タイマーはカウントダウンを続けており、120秒のカウントダウンが0になるまでフラッシュスキルを再度使用することはできません。

2.2 応用シナリオ

  • ウィンドウの調整
  • ページのスクロール
  • パニック買いと狂気のクリック
  • スクロールバーの位置を取得するための遅延読み込み
  • マウスはイベント (クリックなど) を継続的にトリガーしますが、指定された時間内に 1 回だけトリガーします。
  • ……

2.3 実装のアイデア

2.4 手動スロットル コード (メソッド: タイムスタンプとタイマー)

// ---------------------节流1:使用时间戳---------------------
//func 是事件处理程序,delay 是事件执行的延迟时间,单位:毫秒
function throttle (func, delay) {
    //定义初始时间(开始触发事件的时间)
    let start = 0;
    return function () {
        const that = this
        const args = arguments
        // 获取当前时间戳
        let cur =Date.now()
        // 时间间隔大于延迟时间则进入
        if (cur - start >= delay) {
            //执行事件处理程序
            func.apply(that, args);
            //更新初始时间
            start = cur
        }
    }
}
// ---------------------节流2:使用定时器---------------------
//func 是事件处理程序,delay 是事件执行的延迟时间,单位:毫秒
function throttle(func, delay){
    // 自定义一个定时器
    var timer = null;
    return function(){
        var that = this;
        var args = arguments
        // timer为null表示可以发送请求了,否则还在请求中,不执行事件
        if(!timer){
            timer = setTimeout(function(){
                //执行事件处理程序
                func.call(that, args)
                //事件执行完后把定时器清除掉,下次触发事件的时候再设置
                timer = null;
            }, delay)
        }  
    }
}
  •  例:

スロットリング関数が呼び出されない場合、ボタンをクリックするたびに関数呼び出しが実行されます。

<button id="button1">发送了节流请求</button>
const button1Dom = document.getElementById('button1')
button1Dom.addEventListener('click',function(){
    console.log("节流:我发送了消息")
})

 スロットリング機能を使用した後、頻繁にクリックしてリクエストを送信すると、タイマーの期限が切れた後にリクエストが再度送信されます。この期間中にクリックしてリクエストを送信すると、それ以上リクエストは送信されなくなります。

const button1Dom = document.getElementById('button1')
// ---------------------节流1:使用时间戳---------------------
//func 是事件处理程序,delay 是事件执行的延迟时间,单位:毫秒
function throttle (func, delay) {
    //定义初始时间(开始触发事件的时间)
    let start = 0;
    return function () {
        const that = this
        const args = arguments
        // 获取当前时间戳
        let cur =Date.now()
        // 时间间隔大于延迟时间则进入
        if (cur - start >= delay) {
            //执行事件处理程序
            func.apply(that, args);
            //更新初始时间
            start = cur
        }
    }
}
// ---------------------节流2:使用定时器---------------------
//func 是事件处理程序,delay 是事件执行的延迟时间,单位:毫秒
// function throttle(func, delay){
//     // 自定义一个定时器
//     var timer = null;
//     return function(){
//         var that = this;
//         var args = arguments
//         // timer为null表示可以发送请求了,否则还在请求中,不执行事件
//         if(!timer){
//             timer = setTimeout(function(){
//                 //执行事件处理程序
//                 func.call(that, args)
//                 //事件执行完后把定时器清除掉,下次触发事件的时候再设置
//                 timer = null;
//             }, delay)
//         }  
//     }
// }
button1Dom.addEventListener('click',throttle(function(){
    console.log("节流:我发送了消息")
},1000))

頻繁にクリックすると、送信頻度が減ります。 

 

2.5 タイムスタンプとタイマーの実装の違い

最も明らかな違いは、頻繁にクリックすると、タイムスタンプを使用したスロットルは呼び出されるとすぐに実行されますが、タイマーを使用したスロットルは期間の終了時に実行されることがわかります。

第 3 章の概要

  • いわゆるアンチシェイクとは、イベントがトリガーされた後、n 秒間は関数が実行されないことを意味します。イベントが n 秒以内に再度トリガーされると、関数の実行時間が再計算されます。スロットルとは、イベントがトリガーされることを意味します。連続的、ただし n 秒以内 この関数は 1 回だけ実行されます。
  • 関数スロットリングでは、イベントがトリガーされる頻度に関係なく、実際のイベント処理関数が指定時間内に 1 回実行されることが保証されますが、関数アンチシェイクでは最後のイベントの後に関数が 1 回のみトリガーされます。

おすすめ

転載: blog.csdn.net/qq_45796592/article/details/132315247