JS类实例通信

时间:2018-11-21 07:57:58

标签: javascript class

我是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});

1 个答案:

答案 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});