10

Javascript オブジェクトの作成と、setTimeout を使用したそのオブジェクト内でのメソッドの呼び出しに問題があります。さまざまな回避策を試しましたが、常にループの 2 番目の部分でスコープがカスタム オブジェクトではなくウィンドウ オブジェクトになります。警告: 私は JavaScript が初めてです。

私のコード:

$(function() {
 slide1 = Object.create(slideItem);
 slide1.setDivs($('#SpotSlideArea'));
 slide1.loc = 'getSpot';
 slide2 = Object.create(slideItem);
 slide2.setDivs($('#ProgSlideArea'));
 slide2.loc = 'getProg';
 slide2.slide = 1;
 setTimeout('triggerSlide(slide1)', slide1.wait);
 setTimeout('triggerSlide(slide2)', slide2.wait);
});

function triggerSlide(slideObject) {
 slideObject.changeSlide(slideObject);
}

var slideItem = {
 div1: null,
 div2: null,
 slide: 0,
 wait: 15000,
 time: 1500,
 loc: null,
 changeSlide: function(self) {
  this.slide ? curDiv = this.div1:curDiv = this.div2;
  $(curDiv).load(location.pathname + "/" + this.loc, this.slideGo(self));
 },
 setDivs: function(div) {
  var subDivs = $(div).children();
  this.div1 = subDivs[0];
  this.div2 = subDivs[1];
 },
 slideGo: function(self) {
  if(this.slide) {
   $(this.div2).animate({
    marginLeft: "-300px"
   }, this.time);
   $(this.div1).animate({
    marginLeft: "0"
   }, this.time);
   setTimeout('triggerSlide(self)', this.wait);
  } else {    
   $(this.div1).animate({
    marginLeft: "300px"
   }, this.time);
   $(this.div2).animate({
    marginLeft: "0"
   }, this.time);
   setTimeout('triggerSlide(self)', this.wait);
  }   
  this.slide ? this.slide=0:this.slide=1;
 }
}

私の最近の試みは、ヘルパー関数 triggerSlide を作成して、メソッドを介してオブジェクトへの参照を渡そうとすることでしたが、それでもうまくいかないようです。

setInterval を使用できますが、機能します。

  1. タイマーが再起動する前にアニメーションが完了していることを確認したい
  2. そのように問題を回避する方法を学びません。:)
4

3 に答える 3

15

これは、Javascriptプログラマーが言語(およびStackoverflow)を使い始めるために読む必要があります。

Javaとは異なり、関数がどのように宣言されているかに関係なく、オブジェクトへの関数の本質的な「バインド」はありません。オブジェクトコンテキストのバインドは、関数の呼び出し時にのみ発生します。したがって、関数への参照を「setTimeout」のようなものに渡す場合、あるオブジェクトから関数を取得したかどうかはまったく問題ではありません。これは単なる関数であり、「setTimeout」はデフォルトのコンテキストであるwindowオブジェクトを使用して呼び出します。

これを処理する方法はたくさんあります(そして私はそれを「問題」とは呼びません。それは言語の事実であり、非常に強力なものです)。ある種のフレームワークを使用している場合は、より簡単です。

もう1つは、タイムアウトハンドラーと間隔ハンドラーをコードを含む文字列としてバインドしていることです。これはかなり醜い方法なので、関数式、つまり値が関数である式の作成に慣れる必要があります。

たとえば、「slideItem」ハンドラーの場合、次のようにします。

// ...
setTimeout(function() { slideItem.changeSlide(); }, 5000);

このように、タイムアウトメカニズムによって呼び出される関数は、常に「slideItem」オブジェクトをコンテキストとして「changeSlide」を呼び出します。「this」は正しいオブジェクトを指すため、「changeSlide」にその「self」パラメータは必要ありません。

[編集]あなたは実際にjQueryを利用していることに注意してください。これは良いことです。

于 2010-02-25T15:28:12.010 に答える
0

このコードを今すぐテストすることはできませんが、これは役に立ちますか?

setTimeout(function(){triggerSlide(slide1)}, slide1.wait);
于 2010-02-25T15:16:34.967 に答える
0

これはjQueryですよね?へのコールバック パラメータがありますanimate()。アニメーションの完了後に呼び出したい関数を渡すと、jQuery が呼び出しを処理します。コールバックは、必要なスコープを適切にキャプチャする必要があります。

于 2010-02-25T15:18:02.297 に答える