ネタ元はこちら。
自分の場合、Web アプリの UI を開発するときって、たいてい Backbone 使っている。
この Backbone が依存している Underscore には throttle や debounce メソッドがあって、 上記の記事と同じように、メソッドの呼び出し回数を制限できる。
既に導入している Underscore で出来るなら、わざわざ新しいライブラリを導入しなくていいよね。ってわけでサンプル書いてみた。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"/> <title>Debounce Sample</title> </head> <body> <div id="main"> </div> <script id="user_template" type="text/template"> <button class="update-button">Update</button> <div> <label>FirstName:</label> <%= firstName %> </div> <div> <label>LastName:</label> <%= lastName %> </div> <div> <label>RenderCount:</label> <%= renderCount %> </div> </script> <script type="text/javascript" src="lib/jquery.js"></script> <script type="text/javascript" src="lib/underscore.js"></script> <script type="text/javascript" src="lib/backbone.js"></script> <script type="text/javascript"> var User = Backbone.Model.extend({ defaults: { firstName: "", lastName: "", age: 0 } }); var UserView = Backbone.View.extend({ template: _.template($("#user_template").html()), el: $("#main"), events: { "click .update-button": "onUpdate" }, initialize: function() { this.renderCount = 0; // firstName と lastName を 10 回更新すると、 // 合計で 20 回 render が呼ばれてしまう //this.model.on("change", this.render, this); // throttle だと、まず1度描画してから 100ms 待つため、 // 少しちらついてしまう //this.model.on("change", _.throttle(this.render, 100), this); // debounce だと 100ms 待ってから描画するので // ちらつかない this.model.on("change", _.debounce(this.render, 100), this); }, render: function() { var json = this.model.toJSON(); // テンプレートの描画回数も出力する json.renderCount = ++this.renderCount; var html = this.template(json); this.$el.html(html); return this; }, // 2 つのフィールドを10回更新する // 何も対策をしないと、change イベントが 20 回発生する onUpdate: function() { for (var i = 0; i < 10; i++) { this.model.set("firstName", "foo" + i); this.model.set("lastName", "bar" + i); } } }); $(function() { window.main = new UserView({ model: new User() }); window.main.render(); }); </script> </body> </html>
Underscore の方がシンプルに書けて使い勝手が良い。実に自分好みだ。