js防震実戦解説

6519 ワード

なぜ手ぶれ防止技術を使いますか?
フロントエンドの開発では、Windowsのresize、scrollmousedown、mouseoff keyup、keydownなどの頻繁なイベントトリガが発生します.



	
	      


	 
	 
	  	 var search = document.getElementById('search');
			function getUserAction() {
			   console.log('      ',+new Date());
			};

	    search.addEventListener('keyup', getUserAction)
	 


効果図は以下の通りです
内容を入力すると、getsUserアクション関数が実行されます.この例は簡単なので、ブラウザは完全に反応しますが、複雑なコールバック関数やajax要求ならば?仮に1秒で10回トリガしたとしても、各コールバックは1000/10=10 ms以内に完了しなければならない.この問題を解決するために、手ぶれ防止を使ってもいいです.
手振れ防止の原理
イベントがトリガされたn秒後に、コールバック関数を実行します.n秒以内にこのイベントが再起動されたら、時間を再計算します.その結果、頻繁にトリガされるイベントを一度に統合し、最後に実行します.
第一例
コードは以下の通りです
var search = document.getElementById('search');
function getUserAction(e) {
    console.log(e);
    console.log('      ',+new Date());
  };

function debounce(func, wait) {
    var timeout;
    return args => {
      if (timeout) clearTimeout(timeout) 
      timeout = setTimeout(func, wait);
    }
}

const debounceAjax = debounce(getUserAction, 1000)

subBtn.addEventListener('keyup', debounceAjax)
入力後1秒で方法を実行して、入力し終わったら基準として、1秒で方法を実行して、クリックして使用効果を見てください.
第二の例
直ちにこのような必要があります.マウスでイベントを移動して、内容に移動して、すぐに関数を実行します.
この表現に基づいて、私達が書くことができるコード:
function debounce(func, wait, immediate) {
    var timeout;
    return args => {
        let context = this;
        if (timeout) clearTimeout(timeout) 
        if (immediate) {
            //        ,    
            let callNow = !timeout;
            timeout = setTimeout(function() {
                timeout = null;
            },wait) 
          if (callNow) func.call(context, args)
        } else {
            timeout = setTimeout(() => {
                func.call(context, args)
            },wait)
        }
    }
}
debounce(getUserAction、1000、true)マウスをコンテンツに移動して直ちに実行する方法で、最後の移動を基準に1秒後に実行する方法を繰り返します.使用効果を見てください.
完備機能により、手振れ防止機能が追加されました.
function debounce(func, wait, immediate) {
    var timeout,result;
    var debounced =  function() {
      var context = this;
      var args = arguments;

      if (timeout) clearTimeout(timeout);
      if (immediate) {
        //        ,    
        var callNow = !timeout;
        timeout = setTimeout(function() {
          timeout = null;
        }, wait)
        if (callNow) result = func.apply(context, args)
      } else {
        timeout = setTimeout(function() {
          func.apply(context, args)
        }, wait);
      }

      return result;
    }

    debounced.cancel = function() {
    	  clearTimeout(timeout);
    	  timeout = null;
    }

    return debounced;
  }
実行コード:
var setUseAction = debounce(getUserAction, 1000, true);
  container.onmousemove = function() {
    var res = setUseAction();
    console.log(res)
  }

  document.getElementById("button").addEventListener('click', function() {
    setUseAction.cancel();
  })
設定時間は10秒間隔が大きいので、手ぶれをキャンセルしたらすぐ実行します.使用効果を見てください.
参照先:   github.com/mqyqingfeng…
転載先:https://juejin.im/post/5cd27b73e51d453ae37293e7