javascript - 嵌套的网络组件和事件处理

标签 javascript web-component dom-events custom-element

我正在用 javascript 编写一个内存游戏。我为卡片制作了一个网络组件,<memory-card>和一个包含卡片和处理游戏状态的网络组件 <memory-game> . <memory-card>类包含翻转时的图像路径、显示为卡片背面的默认图像、翻转状态和 onclick。函数来处理状态和图像之间的切换。

<memory-game>类有一个 setter 接收图像数组以生成 <memory-cards>从。在 <memory-game> 中处理更新游戏状态的最佳方法是什么?类(class)?我是否应该将额外的事件监听器附加到 <memory-card>有元素还是有更好的方法来解决它?我想要 <memory-card>元素像现在一样只处理它们自己的功能,即根据单击时的状态更改图像。

memory-game.js

class memoryGame extends HTMLElement {
  constructor () {
    super()
    this.root = this.attachShadow({ mode: 'open' })
    this.cards = []
    this.turnedCards = 0
  }

  flipCard () {
    if (this.turnedCards < 2) {
      this.turnedCards++
    } else {
      this.turnedCards = 0
      this.cards.forEach(card => {
        card.flipCard(true)
      })
    }
  }

  set images (paths) {
    paths.forEach(path => {
      const card = document.createElement('memory-card')
      card.image = path
      this.cards.push(card)
    })
  }

  connectedCallback () {
    this.cards.forEach(card => {
      this.root.append(card)
    })
  }
}

customElements.define('memory-game', memoryGame)

内存卡.js

class memoryCard extends HTMLElement {
  constructor () {
    super()
    this.root = this.attachShadow({ mode: 'open' })
    // set default states
    this.turned = false
    this.path = 'image/0.png'
    this.root.innerHTML = `<img src="${this.path}"/>`
    this.img = this.root.querySelector('img')
  }

  set image (path) {
    this.path = path
  }

  flipCard (turnToBack = false) {
    if (this.turned || turnToBack) {
      this.turned = false
      this.img.setAttribute('src', 'image/0.png')
    } else {
      this.turned = true
      this.img.setAttribute('src', this.path)
    }    
  }

  connectedCallback () {
    this.addEventListener('click', this.flipCard())
  }
}

customElements.define('memory-card', memoryCard)

在 Supersharp 回答后执行自定义事件

memory-card.js(提取)

connectedCallback () {
    this.addEventListener('click', (e) => {
      this.flipCard()
      const event = new CustomEvent('flippedCard')
      this.dispatchEvent(event)
    })
  }

memory-game.js(提取)

  set images (paths) {
    paths.forEach(path => {
      const card = document.createElement('memory-card')
      card.addEventListener('flippedCard', this.flipCard.bind(this))
      card.image = path
      this.cards.push(card)
    })
  }

最佳答案

<memory-card> :

  • 使用 CustomEvent() 创建并使用 dispatchEvent() 发送自定义事件

<memory-game> :

  • 使用 addEventListener() 收听您的自定义事件

因为卡片是嵌套在游戏中的,所以事件会自然地冒泡到容器中。

这样 2 个自定义元素将保持松散耦合。

关于javascript - 嵌套的网络组件和事件处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54002383/

相关文章:

javascript - 语义 UI 搜索 - 下拉选择不填充输入

javascript - 在仅使用 javascript 或 jquery 的移动浏览器中准备就绪时,键盘会出现吗?

javascript - 如何在其他条件下应用 Haversine Formula?

javascript - 在页面加载时运行 Jquery 函数一次

javascript - Aurelia js授权

javascript - 如何维护 Web 组件之间的依赖关系而不让其原型(prototype)进入全局命名空间?

javascript - Shadow DOM 中的内容可编辑?

javascript - 有没有办法在不使用 Shadow DOM 的情况下将类似 <slot> 的元素添加到 <template> 中?

javascript - 如何通过JavaScript中的reg表达式检查输入的数字是4位还是7位,然后相应地执行函数hexToRGB?

javascript - 如何通过数字键盘输入验证小数点后两位的输入值?