10

我在构建 Javascript 对象以及使用 setTimeout 在该对象中调用方法时遇到问题。我尝试了各种解决方法,但总是在循环的第二部分,范围成为窗口对象而不是我的自定义对象。警告:我对 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

对于开始使用该语言(以及 Stackoverflow)的 Javascript 程序员来说,这应该是必读的。

与 Java 不同,函数没有内在的“绑定”到任何对象,无论它们是如何声明的。对象上下文的绑定只发生在函数调用时。因此,当您将对函数的引用传递给“setTimeout”之类的东西时,您从某个对象中获取该函数并不重要。它只是一个函数,“setTimeout”将使用默认上下文(window对象)调用它。

有很多方法可以解决这个问题(我不会称其为“问题”;这是语言的一个事实,而且非常强大)。如果您使用某种框架,那就更容易了。

另一件事:您将超时和间隔处理程序绑定为包含代码的字符串。这是一种非常丑陋的做法,因此您应该习惯于形成函数表达式——即,其值为函数的表达式。

例如,对于您的“slideItem”处理程序,您可以这样做:

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

这样,超时机制调用的函数将始终以您的“slideItem”对象作为上下文调用“changeSlide”。您不需要“changeSlide”中的“self”参数,因为“this”将指向正确的对象。

[编辑] 我注意到您实际上正在使用 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 回答