2013-07-04 101 views
1

我正在为我的网站编写简单的滑块。该滑块包含列表项目。我想使用OOP方法。类中的JavaScript/jQuery变量范围(this)

我的实际代码:

var miniSlider = function(objId) 
    { 
     this.obj = $("#" + objId); 
     this.obj.settings = []; 
     this.obj.settings['items'] = $('ul li', this.obj).length; 

     this.pagerNext = this.obj.find("i.next"); 
     this.pagerPrev = this.obj.find("i.prev"); 
     this.pagerNext.on("click", function() { 
     alert(this.obj.settings['items']); 
     }); 
    }; 

我可以调用其他几个滑块(是的,这就是为什么我介绍了一个类):

miniSlider("mini-slider"); 

的问题是,当我在jQuery的this.pagerNext.on(“click”,function(){}); 这个不再是我的对象,而是 - 它成为一个点击元素。点击完成的方式(并支持多滑块)后,如何访问this.obj.settings?

编辑:

这里是与SOF社区:)

var MiniSlider = function(objId) 
{ 
    this.obj = $("#" + objId); 

    this.obj.settings = { 
     items: $("ul li", this.obj).length, 
     autoChangeTime: 8000 
    }; 
    this.obj.activeElement = null; 

    this.pagerNext = this.obj.find("i.next"); 
    this.pagerPrev = this.obj.find("i.prev"); 

    var self = this; 

    this.pagerNext.on("click", function() { 

     self.obj.activeElement = $('li.active', self.obj); 

     if(self.obj.settings.items > 0) 
     { 
      if(self.obj.activeElement.is(':last-child')) 
      { 
       $('li.active', self.obj).removeClass('active'); 
       $('li', self.obj).first().addClass('active'); 
      } 
      else 
      { 
       self.obj.activeElement.next().addClass('active').prev().removeClass('active'); 
     } 
    } 
    }); 
    this.pagerPrev.on("click", function() 
    { 
     self.obj.activeElement = $('li.active', self.obj); 

     if(self.obj.settings.items > 0) 
     { 
      if(self.obj.activeElement.is(':first-child')) 
      { 
       self.obj.activeElement.removeClass('active'); 
       $('li', self.obj).last().addClass('active'); 
      } 
      else 
      { 
       self.obj.activeElement.prev().addClass('active').next().removeClass('active'); 
      } 
     } 
    }); 
    this.obj.parent().on('mouseenter mouseleave', function(e) { 
     if (e.type == 'mouseenter') 
     { 
      $(this).addClass('stop'); 
     } 
     else 
     { 
      $(this).removeClass('stop'); 
     } 
    }); 
    setInterval(function() { 
     if(self.obj.settings.items > 0 && !self.obj.parent().hasClass("stop")) 
     { 
      self.pagerNext.click(); 
     } 
    }, this.obj.settings.autoChangeTime); 

    }; 

,并调用了合作创造了一个全码:

new MiniSlider("mini-slider"); 
+1

与您的问题没有直接关系,但是如果您打算实例化多个这些家伙,您应该使用'new'关键字,如在新的MiniSlider(“mini-slider1”)中;此外,如果您使用它,请使用m大写字母来指示此函数应该用作构造函数。 – Hoffmann

回答

4

亚历克斯给你解决你的回调this问题,但在你的代码的另一个问题。

您呼叫的miniSlider()功能没有new操作:

miniSlider("mini-slider"); 

这意味着,在函数内部,this不是唯一的对象,但实际上是window对象!

您需要使用new操作创建一个单独的对象为每个呼叫:

new miniSlider("mini-slider"); 

但你也应该改变这种功能遵循JavaScript的约定,构造以大写字母开头的名称。说它MiniSlider并使用它,像这样:

new MiniSlider("mini-slider"); 

如果按照这个惯例(其中最有经验的JavaScript程序员做的),它会帮助你记得使用new。如果函数以大写字母开头,则它是一个构造函数,您需要使用new。否则,你不会。

如果您希望能够使用你的构造没有new,这也可能与多一点的代码,例如:

function MiniSlider(objId) { 
    if(this == window) return new MiniSlider(objId); 
    // the rest of your constructor code goes here 
} 

但一般人不打扰和只需使用构造函数中的首字母大写字母作为提醒即可使用new

另外,作为一个建议,我喜欢在变量中保存this时使用一个有意义的名称,然后我始终如一地使用该名称,而不是使用this。这样做,这样它可能看起来像:

var miniSlider = function(objId) { 
    var slider = this; 

    slider.obj = $("#" + objId); 
    slider.obj.settings = []; 
    slider.obj.settings['items'] = $('ul li', slider.obj).length; 

    slider.pagerNext = slider.obj.find("i.next"); 
    slider.pagerPrev = slider.obj.find("i.prev"); 
    slider.pagerNext.on("click", function() { 
     alert(slider.obj.settings['items']); 
    }); 
}; 

为什么我更喜欢使用在大多数地方this和像self在你需要它的另一个变量的方法吗?这样我就不必记住要使用哪一个:我可以总是在代码中使用slider而不是this。 (当然,你可以使用self或其他任何名称;如果我要冒名称的困扰,我只希望有一个更有意义的名字。)

代码中的另一个小问题是这两个语句:

slider.obj.settings = []; 
    slider.obj.settings['items'] = $('ul li', slider.obj).length; 

,当你将要赋予它这样命名的属性,则不应使用的Array。改为使用Object

slider.obj.settings = { 
     items: $('ul li', slider.obj).length 
    }; 

此外,当您使用该属性:当你有数字指标如0,1,2,等,并与对象字面可以同时设置属性阵列,才应使用

 alert(slider.obj.settings['items']); 

你可以更简单地写为:

 alert(slider.obj.settings.items); 

无论哪种方式,做同样的事情。

+0

非常感谢。 –

+1

很高兴帮助。快乐黑客! :-) –

+0

我编辑了一段代码。再次感谢。 –

2

保存在这个参考局部变量,并在嵌套函数中使用该变量而不是this

var self = this; 
this.pagerNext.on("click", function() { 
    alert(self.obj.settings['items']); 
}); 
+0

我想过了,但如果我运行几个滑块,不会有问题吗? –

+0

@PAM:不;它是一个_local_变量。 – SLaks

+0

@PAM Nope。你所做的功能与你所做的范围有关。 –