setTimeout でオブジェクト内のメソッドを実行するにはどうすればよいですか?
-
21-09-2019 - |
質問
プルダウン メニューが、mouseleave イベント時に少し遅れて自動的に閉じるようにしたいと考えています。しかし、それを機能させるのに苦労しています。
オブジェクト内の次のメソッドを考えてみましょう。(jQueryを使用しています)
myObj = {};
myObj.message = "woot!";
myObj.bindEvents = function() {
var that = this;
$("#menuPanel")
.bind("mouseleave", function() {
that.timer = setTimeout(that.closeMenu,500);
});
}
myObj.closeMenu = function() {
// close the menu
alert(this.message);
}
これは機能しません。つまり、this.message は未定義で表示されます。少し調べてみると、その理由が分かりました。:) 「that」参照は、実行時に setTimeout 内のコードでは使用できません。
この種の問題を回避する「最善の」方法は何でしょうか?setTimeout を使用するメソッドで同じオブジェクト内の別のメソッドを呼び出しながら、オブジェクト内のプロパティにアクセスできるようにするにはどうすればよいですか?
よろしくお願いいたします。
解決
ここでの問題は、closeMenu メソッドをそのオブジェクトから切り離していることです。これを実行した場合も同じ問題が発生します。
var closeMenu = myObj.closeMenu; // detaching the method from the object
closeMenu();
このようにメソッドを切り離したり呼び出したりすることは、そのメソッドが作成されたオブジェクトに適用されなくなることを意味します。あなたの例では、ほぼ同じことを行っています。
// Setting the first parameter of setTimeout to be the detached closeMenu method
that.timer = setTimeout(that.closeMenu,500);
最初の方法を修正するには、 call
または apply
メソッド:
var closeMenu = myObj.closeMenu; // detaching the method from the object
closeMenu.apply(myObj);
しかし、それはタイマーでは機能しません。代わりに、匿名関数を作成します。
that.timer = setTimeout(function () { that.closeMenu(); },500);
それも言及する価値があるかもしれません
bind()
- jQuery と混同しないでください $('#selector').bind()
- このメソッドは、しばらくの間、さまざまなブログやいくつかのライブラリ (プロトタイプが最も注目に値します) 上で浮上しており、最終的に に実装されました。 ECMAScript エディション 5.
that.timer = setTimeout(that.closeMenu.bind(that),500);
私は、作成した 1 つまたは 2 つのクラスで同様のメソッドを使用します。これは、作業を簡単にするためです。
所属していません StackOverflow