下面的代码应该为每一张牌添加一个事件监听器,而这是他们的回合,然后删除事件,而这是一个不同的球员的回合。
这不管用。一旦事件最初被设置在他们的第一个回合,那玩家的牌仍然是可点击的。
takeTurn ( playerIndex ) {
console.log(this.name);
let handCards = document.getElementById(this.name).querySelector('.handCards');
let theCards = handCards.querySelectorAll('.handCards .card');
let that = this;
for ( let h = 0; h < theCards.length; h++ ) {
theCards[h].addEventListener("click", function onPlayCard (){
let theseCards = handCards.querySelectorAll('.handCards .card');
let discarded = that.playCard(theCards[h], theseCards, handCards);
that.gameInstance.discardPile.push(discarded);
console.log(that.gameInstance.discardPile);
for ( let e = 0; e < theseCards.length; e++) {
theseCards[e].removeEventListener("click", onPlayCard, false);
}
console.log(that.name + 'is done');
that.gameInstance.nextPlayer( playerIndex );
}, false);
}
}我尝试了here和here的一些想法,但是没有一个完全解决了这个问题。
任何帮助都是非常感谢的。我可能很快就会把头发拔出来。我以为我知道这些东西。
发布于 2016-06-15 14:49:59
问题:
问题是,您正在向每个卡添加一个唯一的函数实例,但随后尝试仅使用单击卡的函数实例来删除它们。这将只删除与添加到单击卡中的实例实际匹配的一张卡。
所以元素0得到处理程序0,元素1得到处理程序1,元素2得到处理程序2,等等.
当单击元素(例如元素2 )时,您将迭代所有元素以删除它们的处理程序,但您将为单击的元素元素2提供处理程序。处理程序2只用于删除元素2,而不是其他元素。
解决方案:
考虑到您当前的代码,我实际上不会给出解决方案,只是说它将涉及维护一个处理程序数组,该数组与它们绑定到的元素并行。它会工作得很好,但我认为重新设计应用程序可能会更好。
--另一种方法:
IMO,重复绑定和未绑定表明在设计应用程序时需要采取不同的方法。
您可以采用面向对象的方法,并将应用程序中的每种类型的项表示为"class“(构造函数)。所以你可以让Game作为一个整体来管理游戏,Card代表一个扑克牌的每个实例,Player来代表每个玩家。
为每一张卡创建一个Card实例。也许还有一些特殊的,比如Dealer,Deck,Discard等。Card可以具有表示其值和适合性的属性,以及引用该卡当前持有者的.owner属性。例如,.owner可以是Player、Discard堆或Deck。
Game对所有这些对象都有引用,以便能够对它们进行协调。它通过将.owner从Deck更改为特定的Player来处理卡片。当Player丢弃Card时,卡的.owner将更改为Discard。
因此,基本上每个对象都保持自己的“状态”。
每个项还可以引用其DOM元素,将处理程序绑定到DOM元素。处理程序将通过this引用DOM元素,但也需要引用其关联实体的数据。大多数人会为每个对象创建一个单独的处理程序,并使用闭包来引用数据。我个人将使用一个鲜为人知的、但非常有用的特性,称为EventListener接口。我让你来研究这个话题。
你到底是怎么安排的取决于你自己。Game应该将一个.owner分配给Card吗?还是Dealer?或者应该将Card传递给所有者(如Player__)并将其分配给.owner属性?或者Card是否应该有一个接收其新所有者并将其分配给自己的.owner属性的方法?你说了算。
希望这能给你一些想法。
https://stackoverflow.com/questions/37758265
复制相似问题