【问题标题】:lit-element: appendChild of ul element in constructor() renders in wrong dom positionlit-element:constructor() 中 ul 元素的 appendChild 呈现在错误的 dom 位置
【发布时间】:2020-06-22 03:16:43
【问题描述】:
  • 试图创建一个发光元素封装的待办事项列表。第一步,尝试创建一个 ul 元素,然后在每次单击按钮时附加一个 li 元素。
  • 虽然我可以通过在 web 组件之前在 html 中预先创建锚 ul 元素来开始工作,但我不想这样做。我希望整个功能都包含在 Web 组件中。
  • 下面是一个合并的 html 文件(包括 lit-element 脚本),展示了我尝试过的几种方法。
    • 如果我在构造函数中创建了 ul 元素,那么我可以成功地附加 li 元素。但是,它们的位置错误(在 html 部分中组件之后的其他元素之后)。
    • 如果我在 render() 的 html 模板文字中创建 ul 元素,则按钮单击不起作用(导致错误“未捕获的类型错误,无法读取属性 'appendChild' of null”)。李>

为什么这些实现不起作用?我什至尝试将其分解为 2 个不同的 Web 组件,其中第一个组件仅负责创建 ul,但我得到相同的“appendChild of null”错误。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <p>(1) from html - before litelement component</p>
  <raf-demo></raf-demo>
  <p>(2) from html - after litelement component</p>
</body>

<script type="module">
  import { LitElement, html, css } from 'https://unpkg.com/lit-element/lit-element.js?module';

  class rafDemo extends LitElement {
    constructor() {
      super();
      var el = document.createElement("ul");
      el.id = "button1";
      el.innerHTML = "Why after (2)? From the component constructor(), I need something that fires only once and renders before render(), outputting between (1) and (2).";
      document.body.appendChild(el); 
    }
    render() {
      return html`
      <ul id="button2">from component in render() - correctly renders inbetween</ul>
      <button @click="${this.button1}">Add li: works, but after (2)</button>
      <button @click="${this.button2}">Add li: should be between (1) and (2), but error</button>
      `;
    }
    button1(event) {
      const li = document.createElement('li');
      li.textContent = "text";
      document.getElementById('button1').appendChild(li);
    }
    button2(event) {
      const li = document.createElement('li');
      li.textContent = "text";
      document.getElementById('button2').appendChild(li);
    }
  }
  customElements.define('raf-demo', rafDemo);
</script>
</html>

感谢您的帮助!

【问题讨论】:

    标签: javascript lit-element lit-html


    【解决方案1】:

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="ie=edge">
      <title>Document</title>
    </head>
    <body>
      <p>(1) from html - before litelement component</p>
      <raf-demo></raf-demo>
      <p>(2) from html - after litelement component</p>
    </body>
    
    <script type="module">
      import { LitElement, html, css } from 'https://unpkg.com/lit-element/lit-element.js?module';
    
      class rafDemo extends LitElement {
        constructor() {
          super();
          var el = document.createElement("ul");
          el.id = "button1";
          el.innerHTML = "Why after (2)? From the component constructor(), I need something that fires only once and renders before render(), outputting between (1) and (2).";
          document.body.appendChild(el); 
        }
        render() {
          return html`
          <ul id="button2">from component in render() - correctly renders inbetween</ul>
          <button @click="${this.button1}">Add li: works, but after (2)</button>
          <button @click="${this.button2}">Add li: should be between (1) and (2), but error</button>
          `;
        }
        button1(event) {
          const li = document.createElement('li');
          li.textContent = "text";
          var elem = this.shadowRoot.getElementById('button2').appendChild(li);
    	  this.shadowRoot.appendChild(elem);
        }
        button2(event) {
          const li = document.createElement('li');
          li.textContent = "text";
          document.getElementById('button2').appendChild(li);
        }
      }
      customElements.define('raf-demo', rafDemo);
    </script>
    </html>

    【讨论】:

    • 啊。 this.shadowRoot.getElementById('button2')。有很多东西要学习 lit-elements。非常感谢!
    • 这将从@CelimpiloMncwango 的一些解释中受益匪浅:)
    猜你喜欢
    • 1970-01-01
    • 2023-03-09
    • 1970-01-01
    • 1970-01-01
    • 2020-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多