lit-element: appendChild элемента ul в конструкторе () отображается в неправильном положении - PullRequest
0 голосов
/ 10 марта 2020
  • Попытка создать список задач с инкапсулированным освещением. В качестве первого шага, пытаясь создать элемент ul, а затем добавлять элемент li при каждом нажатии кнопки.
  • Хотя я могу заставить это работать, начав с предварительного создания элемента anchor ul в html до веб-компонента я не хочу этого делать. Я хочу, чтобы вся функциональность содержалась в веб-компоненте.
  • Ниже приведен консолидированный файл html (включая скрипт с подсветкой), показывающий несколько способов, которыми я пытался это сделать.
    • Если я создаю элемент ul в конструкторе, то я успешно могу добавлять элементы li. Но они находятся в неправильном положении (после других элементов, которые идут после компонента в части html).
    • Если я создаю элемент ul в литерале шаблона html метода render (), тогда нажатия кнопок не работают (в результате возникает ошибка «uncaught typeerror, невозможно прочитать свойство 'appendChild' of null»).

Почему эти реализации не работают? Я даже пытался разбить его на 2 разных веб-компонента, где первый компонент отвечает только за создание 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>

Ваша помощь ценится!

1 Ответ

1 голос
/ 10 марта 2020

<!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>
...