2013-07-04 144 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。你所做的功能與你所做的範圍有關。 –