JavaScript先端性能最適化イベントの手ぶれ防止
6237 ワード
定義:トリガイベント後、所定時間内にコールバック関数は一回しか実行できません.規定時間内にイベントがトリガされた場合、再び規定のタイミングを開始し、新しいイベントの時間を基準として、n秒後に実行します.
アプリケーションシーン:項の検索を入力する時、ユーザは絶えず値を入力する時、手ぶれを防ぎながら資源を要求することを節約します. ボタンをクリックしてください.例えば、いいね.コレクション .
手ぶれ防止には二つの実現方法があります.は、直ちに実行されない:大体ステップ関数呼び出し->>遅延->は、コールバック関数を実行し、遅延時に関数がトリガされると、再度遅延動作を行い、遅延終了後にコールバック関数 を実行する.は直ちに実行します.大体ステップ関数コール->はコールバック関数->遅延を実行します.遅延時に関数がトリガされると、再度遅延動作を行います.遅延終了後はコールバック関数 は実行されません.
直ちに実行しない
私たちが入ってきたfuncは戻り値があると仮定して、関数の実行結果を返します.ただし、immediateがfalseである場合、setTimeoutを使って、func.applyの戻り値を変数に割り当てます.最後にreturnすると、値は常にundefinedです.ですから、私たちはimmediateがtrueの時だけ関数の実行結果を返します.
アプリケーションシーン:
手ぶれ防止には二つの実現方法があります.
直ちに実行しない
function debounce(fun,wait=300){
let timer = null;
return function () {
let self = this,
args = arguments;
timer && clearTimeout(timer);
timer = setTimeout(function () {
method.apply(self,args);
},delay);
}
}
直ちに実行する function debounce(func,wait,immediate){
let timeout;
return function(){
let context = this;
let args = arguments;
if(timeout){
clearTimeout(timeout);
}
if(immediate){
// ,
timeout = setTimeout(function(){
timeout = null;
},wait);
if (!timeout) func.apply(context, args)
}else{
timeout = setTimeout(function(){
func.apply(context,args);
},wait);
}
}
}
拡張私たちが入ってきたfuncは戻り値があると仮定して、関数の実行結果を返します.ただし、immediateがfalseである場合、setTimeoutを使って、func.applyの戻り値を変数に割り当てます.最後にreturnすると、値は常にundefinedです.ですから、私たちはimmediateがtrueの時だけ関数の実行結果を返します.
function debounce(func,wait,immediate){
let timeout,result;
return function(){
let context = this;
let args = arguments;
if(timeout){
clearTimeout(timeout);
}
if(immediate){
// ,
timeout = setTimeout(function(){
timeout = null;
},wait);
if (!timeout) result = func.apply(context, args);
}else{
timeout = setTimeout(function(){
func.apply(context,args);
},wait);
}
return result;
}
}
最後に、私たちはもう一つの小さな需要を考えます.debounce関数をキャンセルしたいです.例えば、debounceの時間間隔は10秒です.immediateはtrueです.これでは、8秒以上待つしかないです.今はボタンがほしいです.クリックした後、手ぶれを防ぐために、再度触発したら、すぐに実行できます. function debounce(func,wait,immediate){
let timeout,result;
let debounced = function(){
let context = this;
let args = arguments;
if(timeout){
clearTimeout(timeout);
}
if(immediate){
// ,
timeout = setTimeout(function(){
timeout = null;
},wait);
if (!timeout) result = func.apply(context, args);
}else{
timeout = setTimeout(function(){
func.apply(context,args);
},wait);
}
return result;
}
debounced.cancel = function(){
clearTimeout(timeout);
timeout = null;
}
}