我正在制作一个表单,用户可以自己和另外5个人自行回复。每个客人都有一个文本字段用于他们的名字,然后是单选按钮(是或否),无论他们是否参加。默认情况下,Guest 1&显示2,然后有一个按钮,用户可以单击以添加另一个客人,直到客人#6。
来宾3 - 6包含在他们自己的对象中:
var guestThree = {
name : document.querySelector('label[for="nameOfThirdGuest"]'),
attendingYes : document.querySelector('label[for="guestThreeAttendingYes"]'),
attendingNo : document.querySelector('label[for="guestThreeAttendingNo"]')
};
var guestFour = {
name : document.querySelector('label[for="nameOfFourthGuest"]'),
attendingYes : document.querySelector('label[for="guestFourAttendingYes"]'),
attendingNo : document.querySelector('label[for="guestFourAttendingNo"]')
};
var guestFive = {
name : document.querySelector('label[for="nameOfFifthGuest"]'),
attendingYes : document.querySelector('label[for="guestFiveAttendingYes"]'),
attendingNo : document.querySelector('label[for="guestFiveAttendingNo"]')
};
var guestSix = {
name : document.querySelector('label[for="nameOfSixthGuest"]'),
attendingYes : document.querySelector('label[for="guestSixAttendingYes"]'),
attendingNo : document.querySelector('label[for="guestSixAttendingNo"]')
};
我使用以下函数隐藏客人的3 - 6,然后将其转换为上述对象的方法:
function hideFields() {
this.name.style.display = "none";
this.attendingYes.style.display = "none";
this.attendingNo.style.display = "none";
}
我也与showFields中的上述函数相反:
function showFields() {
this.name.style.display = "block";
this.attendingYes.style.display = "block";
this.attendingNo.style.display = "block";
}
所以这里的想法是,当点击添加访客按钮(分配给变量addGuest)时,将添加访客#3。然后,当它再次被点击时,将添加#4号客座,依此类推,直到#6。我已将guestThree - guestSix对象添加到以下数组中:
var extraGuests = [guestThree, guestFour, guestFive, guestSix];
然后使用以下for循环:
for (var guest = 0; guest < extraGuests.length; guest++) {
addGuest.onclick = function() {
extraGuests[guest].showFields();
};
}
但这不起作用。我通过测试发现,guest方式一直循环到4而不执行showFields方法。如果我要在onclick事件之后添加一个中断,那么guestThree将显示但是就是这样(显然因为这是中断的工作原理)但是这至少表明循环按照我希望的方式工作 - 在某种程度上。
所以我问你们的是 - 我做错了什么?如何使guest变量不直接循环到4?我需要每次迭代都是0,1,2,最后是3,据我所知,这正是应该发生的事情?
干杯!
答案 0 :(得分:3)
有两个问题:
首先,您要在每个循环上覆盖onclick
上的addGuest
,因此只有最后一个分配才能生存。因此,如果我们解决第二个问题(下面),您仍然只会显示最后一组字段。可能,我们希望处理程序分配一次,并让它显示&#34; next&#34;一组字段。
第二个问题是,您分配给onclick
的功能对guest
变量有持久参考,而不是副本在创建函数时的em> of it。所以稍后,当函数被调用时,它会在guest
循环结束后看到值for
。解决这个问题的主要选择是构建函数,Function#bind
中描述了var extraGuests = [guestThree, guestFour, guestFive, guestSix];
var nextGuest = 0;
addGuest.onclick = function() {
var guest = extraGuests[nextGuest];
if (guest) {
++nextGuest;
guest.showFields();
}
};
。但由于我们不需要或不需要循环,因此无关紧要。
相反,我建议一个变量告诉你要揭示的下一组字段是什么,然后只是一个使用它的函数:
{{1}}
答案 1 :(得分:2)
您已经closed over a loop variable,这意味着在他们被调用时,您的点击处理程序都会查看guest
的单个值,即extraGuests.length
(它在循环完成时定义的值)。
您需要在循环执行时捕获循环变量which can be done easily using an Immediately-invoked function expression。 :
for (var guest = 0; guest < extraGuests.length; guest++) {
(function(ind){
addGuest.onclick = function() {
extraGuests[ind].showFields();
};
})(guest);
}
使用较新的语言功能可能有更好/更简洁的方法。
答案 2 :(得分:0)
也许这就是。
var guest = 0;
addGuest.addEventListener('click', function() {
if(guest < extraGuests.length)
extraGuests[++guest].showFields();
}, false);