javascript - 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});
解决方案
将任何组件的范围限制在自身范围内是一种很好的做法(封装)。也就是说,一张卡片不应该知道还有多少张其他卡片存在。为了保持卡片解耦,实现这一目标的常用方法是使用自定义事件。
想象它是这样的:一张被点击的卡片向房间里喊“我被点击了”,并依赖于有人听到并对此做出反应,然后才知道该怎么做。如果没有人做出反应,您的代码仍然不会抛出错误。
为了在您的场景中工作,您需要卡片的主机元素,因为事件会在 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});
推荐阅读
- ruby-on-rails - Ruby on Rails 中是否有一种内置方法可以避免将过时形式的数据写入数据库?
- javascript - jqxgrid rowselect事件未触发
- jquery - JQuery 时间微调器图标颜色
- python - 从包含python中字符串和数字的列表中获取最小值和最大值,然后用这些值替换字符串?
- python - 文件未在烧瓶中上传
- omnet++ - 在 omnet++ 上禁用 IEEE802.15.4 中的 CSMA 协议
- jquery - jQuery 3.5.1 和 CSP 脚本-src-elem
- android - FragmentContainer 通过导航消失了
- javascript - 为什么有些网站在返回 JSON 数据时格式相同?
- vue.js - 隐藏动态生成的输入列表中的一项,除非列表中的其他输入在 vue / vuetify 中具有值