下面的代码应该为玩家手中的每张扑克牌添加一个事件监听器,然后轮到他们,然后在不同的玩家轮换时删除这些事件。
它不起作用。一旦事件最初设置在他们的第一个回合,该玩家的牌仍然可以点击。
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中的一些想法,但没有一个能够解决问题。
感谢任何帮助。我很快就会拔掉头发。我以为我知道这些东西。
答案 0 :(得分:1)
问题:
问题是你要为每张卡添加一个独特的功能实例,但是后来尝试仅使用所点击的卡的功能实例将它们全部删除。这只会删除实际上与添加到点击卡中的实例匹配的一张卡。
因此,元素0获取处理程序0,元素1获取处理程序1,元素2获取处理程序2,依此类推......
当单击一个元素时,比如元素2,然后迭代所有元素以移除它们的处理程序,但是你为所单击的元素2提供了处理程序。处理程序2仅对删除元素2,而不是其他元素。
解决方案:
我实际上并没有根据你当前的代码给出一个解决方案,除了说它将涉及维护一个与它们绑定的元素并行的处理程序数组。它会工作得很好,但我认为应用程序的重新设计可能会更好。
另一种方法:
IMO,重复绑定和解除绑定表明在设计应用时需要采用不同的方法。
您可以采用面向对象的方法,并将应用中的每种类型的项目表示为&#34;类&#34; (构造函数)。因此,您需要Game
来管理整个游戏,Card
代表扑克牌的每个实例,Player
代表每个玩家。
为每张卡片创建一个Card
个实例。对于丢弃堆,也许是其他特殊的,例如Dealer
或Deck
和Discard
。 Card
可以具有表示其值和套装的属性,以及引用该卡的当前持有者的.owner
属性。 .owner
可以是Player
,Discard
桩或Deck
。
Game
引用了所有这些对象,以便它可以协调它们。它通过将.owner
从Deck
更改为某个Player
来处理这些卡片。当Player
丢弃Card
时,该卡的.owner
会更改为Discard
。
所以基本上每个对象都保持自己的状态&#34;。
每个项目还可以引用其绑定处理程序的DOM元素。处理程序将通过this
引用DOM元素,但它也需要引用其关联实体的数据。大多数人会为每个对象创建一个单独的处理程序,并使用闭包来引用数据。我个人会使用一个鲜为人知的极有用的功能,称为 EventListener接口。我会留给你研究这个话题。
你如何设置它取决于你。 Game
应该.owner
分配给Card
吗?还是Dealer
?或者Card
是否应该传递给所有者(例如Player
)并让它分配.owner
属性?或者Card
是否应该有一个方法来接收新的所有者并将其分配给自己的.owner
属性?由你决定。
希望无论如何这会给你一些想法。