Встроенный обработчик щелчка мыши в ванильных веб-компонентах

Когда мы настраиваем встроенные обработчики щелчков внутри ванильных веб-компонентов, this ниже ссылается на элемент h1.

export default class wc_parent extends HTMLElement {
  constructor() {
    super()
    this.attachShadow({mode: 'open'})
  }

  render() {
    const template = document.createElement('template')
    template.innerHTML = `
      <h1 onclick="this.handle_click(event)">hello</h1>
      <style>
        :host {
          display: block;
        }
      </style>
    `

    this.shadowRoot.appendChild(
      template.content.cloneNode(true)
    )
  }

  handle_click(e) {
    console.log(e)
  }

  connectedCallback() {
    this.render()
  }
}
Вход в полноэкранный режим Выход из полноэкранного режима

Если мы хотим обрабатывать щелчок в режиме inline, нам нужно сделать так, чтобы он работал вот так, внутри connectedCallback():

connectedCallback() {
  this.shadowRoot.addEventListener('click', this.handle_click)
}
Вход в полноэкранный режим Выход из полноэкранного режима

Жизнь станет немного проще, если мы сможем сделать так, чтобы this внутри onclick="this.handle_click(event)" указывал на компонент вместо объекта window, как в React. Я думал добавить свойство окна и указать на этот компонент window[this.localName] = this, а затем заменить this на window[this.localName] внутри метода render().

export default class wc_parent extends HTMLElement {
  constructor() {
    super()
    this.attachShadow({mode: 'open'})
    window[this.localName] = this 
  }

  render() {
    const template = document.createElement('template')
    template.innerHTML = `
      <h1 onclick="this.handle_click(event)">hello</h1>
      <style>
        :host {
          display: block;
        }
      </style>
    `
    // replace this to window['wc-parent']
    template.innerHTML = template.innerHTML.replace(
      /this/g, 
      `window['${this.localName}']`
    )

    this.shadowRoot.appendChild(
      template.content.cloneNode(true)
    )
  }

  handle_click(e) {
    console.log(e)
  }

  connectedCallback() {
    this.render()
  }
}
Вход в полноэкранный режим Выход из полноэкранного режима

Вот как это отображается в front end, если мы проверим элементы HTML. Эта часть onclick="window['wc-parent'].handle_click(event)" имеет смысл, так как она ясно указывает на то, что мы можем найти этот метод внутри компонента wc-parent.

<wc-parent>
  #shadow-root (open)
    <h1 onclick="window['wc-parent'].handle_click(event)">hello</h1>
</wc-parent>

Вход в полноэкранный режим Выход из полноэкранного режима

Оцените статью
devanswers.ru
Добавить комментарий