我是js类的新手,我认为我做得不好。
我想在这里实现一个简单的事情。在一张卡片上,单击我要隐藏所有其他卡片。但是,如果从其中一张卡的内部触发事件,我该如何到达其他卡?
class Cards {
constructor(args){
this.list = [];
this.amm = args.amm;
this.createCards();
}
createCards(){
for(var i=0; i<this.amm; i++){
this.list.push( new Card( {id: i} ) );
}
}
}
class Card {
constructor(args){
this.id = args.id;
this.el = null;
this.createCard();
this.addEvents();
}
createCard(){
this.el = document.createElement("div");
this.el.style.width = "60px";
this.el.style.height = "100px";
this.el.style.backgroundColor = "red";
this.el.style.margin = "5px";
this.el.style.float = "left";
document.body.appendChild(this.el);
}
addEvents(){
let _this = this;
this.el.onclick = function(){
_this.el.style.opacity = 0.7;
_this.hideOtherCards(_this.id);
};
}
hideOtherCards(id){
// how to hide other cards?
}
}
var myCards = new Cards({amm: 5});
答案 0 :(得分:3)
优良作法( encapsulation )将所有组件的范围限制在自身范围内。也就是说,一张卡片不应该知道 ,或者多少张其他卡片。要使卡保持 去耦 ,一种常见的实现方法是利用自定义事件。
像这样想象:被点击的卡片在“我被点击”的房间里喊叫,并且依靠某人听到并对此做出反应,然后知道该怎么做。如果没有人做出反应,您的代码仍然不会引发错误。
要使其在您的情况下正常工作,当事件在DOM中冒出时,您需要一个卡元素作为主机元素,但不要在同级中冒出来。
长话短说,这就是我要做的:
编辑:实际上,myCards
类应该负责创建主机元素,并监听card-clicked
。
class Cards {
constructor(args){
this.list = [];
this.el = null;
this.amm = args.amm;
this.createCardHost();
}
createCardHost() {
this.el = document.createElement('div');
this.createCards();
this.el.addEventListener('card-clicked', (e) => {
this.list.forEach(card => {card.id === e.detail.id ? card.el.style.opacity = 0.7 : card.el.style.opacity = 0.1})
})
for (const card of this.list) {
this.el.appendChild(card.el)
}
document.body.appendChild(this.el);
}
createCards(){
for(var i=0; i<this.amm; i++){
this.list.push( new Card( {id: i} ) );
}
}
}
class Card {
constructor(args){
this.id = args.id;
this.el = null;
this.createCard();
this.addEvents();
}
createCard(){
this.el = document.createElement("div");
this.el.style.width = "60px";
this.el.style.height = "100px";
this.el.style.backgroundColor = "red";
this.el.style.margin = "5px";
this.el.style.float = "left";
}
addEvents(){
this.el.addEventListener('click', () => {
this.el.style.opacity = 0.7;
// throw a 'card-clicked' event here
const cardClicked = new CustomEvent('card-clicked', { bubbles: true, cancelable: true, detail: { id: this.id }});
this.el.dispatchEvent(cardClicked);
});
}
}
var myCards = new Cards({amm: 5});