【问题标题】:addEventListener in shadow DOM阴影 DOM 中的 addEventListener
【发布时间】:2019-12-10 18:56:00
【问题描述】:

我正在尝试使用 addEventListener 从 Shadow DOM 获取用户输入,但我没有得到任何响应,也没有任何错误。对元素的引用正常工作,因此 console.log(input) 打印出正确的元素。相同的代码在没有影子 DOM 的情况下工作得很好,但我必须将它包含在我的项目中。这是我的代码(这些事件当然只是为了检查):

const template = document.createElement('template')
template.innerHTML = /* html */`
<div id="username">
  <p>Please choose your username!</p>
  <input id="username_input" type="text" placeholder="enter username">
  <button>Ok</button>
</div>
`
/**
 * @class Quiz
 * @extends {window.HTMLElement}
 */
export class Quiz extends window.HTMLElement {
  constructor () {
    super()
    this.attachShadow({ mode: 'open' })
    this.shadowRoot.appendChild(template.content.cloneNode(true))
  }

  getUserName () {
    const button = this.shadowRoot.querySelector('button')
    const inputUname = this.shadowRoot.querySelector('#username input')
    console.log(button)
    button.addEventListener('click', event => console.log('badum tss'))
    inputUname.addEventListener('input', event => console.log('badums tss'))
  }
}
window.customElements.define('user-name', Quiz)

app.js 代码:

import { Quiz } from './quiz.js'

var x = new Quiz()
x.getUserName()

html:

<!doctype html>
<html lang="">
    <head>
        <meta charset="utf-8">
        <title></title>
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <script type="module" src="js/app.js"></script>
        <link rel="stylesheet" href="css/style.css">
    </head>
    <body>
        <user-name></user-name>
        <script nomodule src="build.js"></script>
    </body>
</html>

【问题讨论】:

  • 1) 我没有看到任何实际调用getUserName() 的代码,因此您的事件侦听器永远不会附加,2)“输入”不是本机事件。它可以是一个自定义事件,但您需要定义它,并向它广播一些代码。我没有看到这些东西的代码。
  • 如果没有更多信息,这里有一些内容可能会为您指明正确的方向。其中一些与您的问题无关,但影子 dom 代码示例可能会有所帮助。 stackoverflow.com/questions/55139670/…
  • 是的,对不起,我只复制了这个模块。我已经更新了这个问题。好的,但为什么“点击”不起作用?如果我不使用 Shadow DOM,这段代码可以正常工作,所以我有点迷茫......

标签: javascript html events shadow-dom


【解决方案1】:

问题很简单。您的代码实际上创建了两个&lt;user-name&gt;s。

一个是在html中静态创建的:

<user-name></user-name>

另一个是通过javascript动态创建的:

var x = new Quiz()

动态的永远不会附加到文档中,因此您只能在页面上看到静态的。由于您只在动态监听器上调用getUserName(),因此clickinput 监听器永远不会添加到静态监听器。这就是你没有得到任何回应的原因。

我建议你把addEventListener()放在构造函数中,那么静态的应该可以正常工作。

【讨论】:

  • 是的,成功了,谢谢!是否有可能以某种方式修复它,以免构造函数中的代码过多?
  • 您的意思是希望构造函数中的代码行数尽可能少?您可以将addEventListener() 保留在原来的位置,并在构造函数中显式调用this.getUserName(),尽管我看不出这样做有什么好处。
猜你喜欢
  • 2012-07-01
  • 2019-08-26
  • 2016-11-04
  • 2019-07-21
  • 2021-07-13
  • 2019-11-09
  • 2011-07-23
  • 1970-01-01
  • 2015-06-30
相关资源
最近更新 更多