2013-07-19 73 views
6

我是一名中級前端JS開發人員,我嘗試使用Chris Coyyer概述的模塊模式here使用「模塊模式」時jQuery點擊事件不起作用

但是,當我在設置中存儲jQuery選擇器時,我無法使用它觸發單擊事件。看到下面的代碼與我的意見...任何幫助非常感謝!

var s, 
TestWidget = { 
    settings: { 
    testButton: $("#testing") 
    }, 
    init: function() { 
    s = this.settings; 
    this.bindUIActions(); 
    }, 
    bindUIActions: function() { 
    console.log(s.testButton); // This works: [context: document, selector: "#testing", constructor: function, init: function, selector: ""…] 

    //This doesn't work - why????? 
    s.testButton.click(function() { 
     //Why isn't this triggered? 
     alert('testButton clicked'); 
    }); 

    /*This works, obviously: 
    $('#testing').click(function() { 
     alert('testButton clicked'); 
    }); 
    */ 

    } 
}; 
$(document).ready(function() { 
    TestWidget.init(); 
}); 

回答

10

問題是你在DOM準備好之前初始化了$("#testing"),所以這個jQuery對象是空的。

一個簡單的解決方案是將所有的代碼放在準備好的回調中。

另一條是與

settings: { 
    }, 
    init: function() { 
    s = this.settings; 
    s.testButton = $("#testing"); 
    this.bindUIActions(); 
    }, 

更換

settings: { 
    testButton: $("#testing") 
    }, 
    init: function() { 
    s = this.settings; 
    this.bindUIActions(); 
    }, 

但很難讓你爲什麼用這麼多的代碼,這樣一個簡單的事情。你可能會過度使用這個模式,它不是很乾淨,因爲你有兩個全局變量sTestWidget,當時已經有很多了。

下面是這將是,在我看來,更清潔,同時仍使用模塊(IIFE variant)代碼的一個微小的變化:

TestWidget = (function(){ 
    var settings = {}; 
    return { 
     init: function() { 
      settings.testButton = $("#testing"); 
      this.bindUIActions(); 
     }, 
     bindUIActions: function() { 
      console.log(settings.testButton); 
      settings.testButton.click(function() { 
       alert('testButton clicked'); 
      }); 
     } 
    } 

})(); 
$(document).ready(function() { 
    TestWidget.init(); 
}); 

settings保持在關閉和在全球不漏命名空間。請注意,即使這個版本沒有意義,如果你沒有做更多的模塊。

+2

+1「過度使用模式」 – Bergi

+1

我認爲op只是簡單地遵循CSS技巧來理解模式。也許手頭有更大的任務?如果意圖是通過模塊化理解封裝,我推薦閱讀addy osmani的設計模式。 – stavarotti

+1

在所有內容之後,將腳本塊置於頁面底部可以解決此問題。這將使代碼完全放置在模塊內,而不會泄漏到全局名稱空間。 –