2015-12-11 38 views
0

當我運行這個程序只有一個Cat(var cat1)的實例時,它完美的工作。 當我運行第二個實例(var cat2),事情停止工作。構造函數不工作的多個實例

function main() { 
    var catPic = document.getElementById('catPic'); 
    var numClicks = 0; 
    var numCats = -1; 
    var scope; 

    var Cat = function Cat(name, url) { 
     numCats++; 
     scope = this; 
     this.name = name; 
     this.url = url; 
     this.numClicks = 0; 
     this.clickId = 'clicks' + numCats; 

     window.onload = function() { 

      //Puts a new Cat on the screen. The name, image, and # of clicks will be shown. 
      appendCat(scope.name, scope.url, scope.clickId, scope.numClicks, numCats); 

     } 
    }; 

    var cat1 = new Cat('Bob', 'https://lh3.ggpht.com/nlI91wYNCrjjNy5f-S3CmVehIBM4cprx-JFWOztLk7vFlhYuFR6YnxcT446AvxYg4Ab7M1Fy0twaOCWYcUk=s0#w=640&h=426'); 
    var cat2 = new Cat('Samantha', 'https://lh3.ggpht.com/nlI91wYNCrjjNy5f-S3CmVehIBM4cprx-JFWOztLk7vFlhYuFR6YnxcT446AvxYg4Ab7M1Fy0twaOCWYcUk=s0#w=640&h=426'); 
} 

main(); 

問題與appendCat()有關;功能。

//Puts a new Cat on the screen. The name, image, and # of clicks will be shown. 
    function appendCat(name, url, clickId, numClicks, numCats) { 
     document.body.appendChild(document.createElement('div')); 
     document.getElementsByTagName('div')[numCats].setAttribute('id', 'cat' + numCats); 

     document.body.getElementById().appendChild(document.createElement('h2')); 
     document.getElementsByTagName('h2')[numCats].textContent = name; 

     document.body.appendChild(document.createElement('img')); 
     document.getElementsByTagName('img')[numCats].setAttribute('id', name); 
     document.getElementsByTagName('img')[numCats].setAttribute('src', url); 

     document.body.appendChild(document.createElement('p')); 
     document.getElementsByTagName('p')[numCats].setAttribute('id', clickId); 
     document.getElementsByTagName('p')[numCats].textContent = numClicks; 

     document.body.appendChild(document.createElement('br')); 
     document.body.appendChild(document.createElement('br')); 
    } 

當此功能的這些前兩行運行,document.getElementsByTagName( 'DIV')[numCats]計算結果爲未定義。我不知道爲什麼會發生這種情況。 Console.log()對我也沒什麼幫助。謝謝!

+0

這是實際的代碼嗎?不知道如何運行'document.body.getElementById()'而不會出錯。另外,有點奇怪,你會把'var scope'放在main()中,而不是放在'cat()'函數中。就像這樣,每個新的'Cat'都會將它的'this'設置爲所有*'Cat'對象的'範圍'。 –

+0

它不是C++。爲什麼在構造函數中使用'window.onload'和'appendCat'?而你的'scope.numClicks'總是0. –

+0

謝謝!我已經完全刪除了範圍變量。我也移動了所有不應該在其他地方的構造函數中的東西。我絕對不會犯我在這段代碼中犯的錯誤,這要歸功於你們兩個(當然還有@Ethan Lynn)。 –

回答

0

首先您的scope變量需要在構造函數中聲明,以便window.onload指的是正確的實例。否則,window.onload處理程序將引用在時間window.onload觸發器處設置的任何值範圍 - 這將始終是第二個實例。其次,您不需要設置window.onload,而需要使用window.addEventListener("load", function() { ... }"),以便每個實例都擁有自己的偵聽器。 window對象只有一個onload屬性,因此多次設置它不會創建多個偵聽器,而只是覆蓋前一個偵聽器。

作爲一個額外的說明,我會建議取消該事件從構造處理,並把它放在外面是這樣的:

var cats = [ 
    new Cat(...), 
    new Cat(...) 
]; 
window.addEventListener('load', function() { 
    cats.forEach(function (cat) { 
     appendCat(cat.name, cat.url, cat.clickId, cat.numClicks, cats.length); 
    }); 
}); 

這將消除scopenumCats變量,並將所有window.onload funtionality一個處理程序而不是每個實例都有一個處理程序。

+0

謝謝!閱讀您的答覆後發生了許多facepalming。另外,我最終使用了for()循環而不是forEach(更好的性能)。 –

+0

你跑過他的代碼了嗎?事實上,我看到很多其他問題! – brk