この記事の例では、JavaScript 関数のスロットルの概念と使用法について説明します。参考のために皆さんと共有してください。詳細は次のとおりです:
最近Webページを作成しているときに、ブラウザウィンドウが変更されたときに一部のページ要素のサイズを変更する必要があったため、自然にサイズ変更を考えましたこれは私が書いたものです
<!DOCTYPE html> <html> <head> <title>Throttle</title> </head> <body> <script type="text/javascript"> n=0; function resizehandler(){ console.log(new Date().getTime()); console.log(++n); } window.onresize=resizehandler; </script> </body> </html>
関数は実装されましたが、ドラッグしてブラウザウィンドウのサイズを変更するときにコンソールを見ました
はい、単純なドラッグで私のresizeHandler()が作成されました実際、このメソッドは 52 回実行されますが、これは私が望んでいる効果ではありません。実際、ウィンドウ サイズを 1 回変更するだけでも、ajax を使用するコードが非常に複雑です。これを 52 回呼び出す必要がありますが、これは悪いことではありません。
関数の調整
実際、私の本来の目的は、ウィンドウのサイズ変更後にページを調整することだけであり、ウィンドウのサイズ変更イベントはトリガーされません。サイズ変更が完了する具体的な頻度は分かりませんが、ウィンドウサイズが変更されなくなるまで呼び出し続けます。実際、同様のメカニズムは、短期間に繰り返しトリガーされるマウスムーブです。
「JavaScript 高度なプログラミング」には、この問題に対処するための特別な関数スロットルがあります
function throttle(method,context){ clearTimeout(method.tId); method.tId=setTimeout(function(){ method.call(context); },500); }
原理は非常に簡単で、関数が 500 ミリ秒以内に再度呼び出された場合、関数の実行を 500 ミリ秒遅らせます。ミリ秒後、削除します。呼び出されると、この呼び出しは 500 ミリ秒後に実行されます。このようにして、作成したコードを
<script type="text/javascript"> n=0; function resizehandler(){ console.log(new Date().getTime()); console.log(++n); } function throttle(method,context){ clearTimeout(method.tId); method.tId=setTimeout(function(){ method.call(context); },500); } window.onresize=function(){ throttle(resizehandler,window); }; </script>
に変更できます。ドラッグして試してみてください。一度だけ実行されます
別の方法
インターネット上には機能制限ソリューションもあります。これを実行します
function throttle(method,delay){ var timer=null; return function(){ var context=this, args=arguments; clearTimeout(timer); timer=setTimeout(function(){ method.apply(context,args); },delay); } }
Call試してみてください。同じ効果です
<script type="text/javascript"> n=0; function resizehandler(){ console.log(new Date().getTime()); console.log(++n); } function throttle(method,delay){ var timer=null; return function(){ var context=this, args=arguments; clearTimeout(timer); timer=setTimeout(function(){ method.apply(context,args); },delay); } } window.onresize=throttle(resizehandler,500);//因为返回函数句柄,不用包装函数了 </script>
比較
違いは、2 番目のメソッドで追加された関数が実行時間を遅らせることです。この関数は、最初の解決策で簡単に使用できます。 . パラメータを追加することです。
しかし、最初の解決策は tId を関数の変数として設定して保存しますが、2 番目の解決策はそれを保存するクロージャーを作成します。個人的には、違いは大きくないと思います。最初の方がシンプルで効率的で気に入っています。
新しい要件
ある日、Baidu ホームページの自動入力プロンプトと同様のものを作成しました。キーアップ イベントをテキストにバインドすると、キーボードがポップアップするたびに自動的にプロンプトが表示されますが、これは望ましくありません。頻繁にそのようにプロンプトが表示されるため、上記の方法を使用しましたが、入力プロセス中はまったくプロンプトが表示されず、入力を停止した後にのみプロンプトが表示されました。コードを調べたところ、これは真実ではないことがわかりました。ユーザーが 500 ミリ秒以内にキーボードをタッチして押すことができる限り、プロンプト機能は継続的に遅延し、停止したときにのみプロンプトが表示されます。意味のない。
機能スロットルに基づいて一定の間隔で実行できますか?
小さな変更
インターネットで検索した後、2 番目の記述方法 (関数の複数の変数を展開する最初の方法は少し悪いと感じます) に基づいていくつかの変更を加え、パラメータを固定間隔として追加できます。実行される
function throttle(method,delay,duration){ var timer=null, begin=new Date(); return function(){ var context=this, args=arguments, current=new Date();; clearTimeout(timer); if(current-begin>=duration){ method.apply(context,args); begin=current; }else{ timer=setTimeout(function(){ method.apply(context,args); },delay); } } }
このように、間隔の長さを判断するたびに、設定時間を超えた場合にすぐに実行されます。今の例で効果を試してみてください
window.onresize=throttle(resizehandler,100,200);
案の定、どちらでもありません。頻繁に実行されたり、最後に実行されたりすることはありません
この記事が皆様の JavaScript プログラムのデザインに役立つことを願っています。
JavaScript 関数のスロットリングの概念と使用例の詳細な説明については、PHP 中国語 Web サイトに注目してください。