构造函数的多个实例不起作用
Multiple instances of constructor not working
当我 运行 这个程序只有一个 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() 对我帮助不大。谢谢!
首先需要在构造函数中声明您的 scope
变量,以便 window.onload
引用正确的实例。否则,两个 window.onload
处理程序都将引用在 window.onload
触发器时设置为范围的任何值——这将始终是第二个实例。其次,您需要使用 window.addEventListener("load", function () { ... }")
而不是设置 window.onload
,以便每个实例都有自己的侦听器。 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);
});
});
这将删除 scope
和 numCats
变量并将所有 window.onload
功能移动到一个处理程序,而不是每个实例都有一个处理程序。
当我 运行 这个程序只有一个 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() 对我帮助不大。谢谢!
首先需要在构造函数中声明您的 scope
变量,以便 window.onload
引用正确的实例。否则,两个 window.onload
处理程序都将引用在 window.onload
触发器时设置为范围的任何值——这将始终是第二个实例。其次,您需要使用 window.addEventListener("load", function () { ... }")
而不是设置 window.onload
,以便每个实例都有自己的侦听器。 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);
});
});
这将删除 scope
和 numCats
变量并将所有 window.onload
功能移动到一个处理程序,而不是每个实例都有一个处理程序。