首页 > 解决方案 > JS 类实例通信

问题描述

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

标签: javascriptclass

解决方案


将任何组件的范围限制在自身范围内是一种很好的做法(封装)。也就是说,一张卡片不应该知道还有多少其他卡片存在。为了保持卡片解耦,实现这一目标的常用方法是使用自定义事件

想象它是这样的:一张被点击的卡片向房间里喊“我被点击了”,并依赖于有人听到并对此做出反应,然后才知道该怎么做。如果没有人做出反应,您的代码仍然不会抛出错误。

为了在您的场景中工作,您需要卡片的主机元素,因为事件会在 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});


推荐阅读