Lit-Element:哪个事件用于 DOM 更新?

Sir*_*rko 6 javascript web-component lit-element

github.com/Polymer/lit-element 上的文档描述了生命周期,如果某些 lit-element的属性发生更改。但是,如果元素的 DOM 内容发生更改,我似乎找不到有关生命周期的任何文档。

所以假设我有一些嵌套的 DOM 结构,我最外层的元素应该根据 DOM 内容显示一些东西。为简单起见,下面的示例将仅显示给定类型的子元素的数量。

现在,我的应用程序会插入一个新的嵌套元素(单击test下面的按钮)。在这一点上,我想更新显示的计数。

从我的测试来看,render()在这种情况下似乎不会再次调用,也不会updated()

我需要监听哪个事件或者我需要实现哪个函数来识别这样的变化?

我目前唯一的解决方法是requestUpdate()在 DOM 更新后手动使用,但我认为此类更改应该由 lit-element 本身处理。

  document.querySelector( 'button' )
          .addEventListener( 'click', () => {
            const el = document.querySelector( 'my-element' );
            el.insertAdjacentHTML( 'beforeend', '<my-nested-element>new addition</my-nested-element>' );
          })
Run Code Online (Sandbox Code Playgroud)
my-element, my-nested-element {
  display: block;
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://unpkg.com/@webcomponents/webcomponentsjs@latest/webcomponents-loader.js"></script>

<!-- Works only on browsers that support Javascript modules like Chrome, Safari, Firefox 60, Edge 17 -->
<script type="module">
  import {LitElement, html} from 'https://unpkg.com/@polymer/lit-element/lit-element.js?module';

  class MyElement extends LitElement {
    constructor(){
      super();
      this.number = this.querySelectorAll( 'my-nested-element' ).length;
    }
  
    render() {
      return html`<p>number of my-nested-element: ${this.number}</p> 
                  <slot></slot>`;
    }  
  }
  customElements.define('my-element', MyElement);
  
	class MyNestedElement extends LitElement {
    render() {
      return html`<slot></slot>`;
    }  
  }
  customElements.define('my-nested-element', MyNestedElement);
</script>

<my-element>
  <my-nested-element>first</my-nested-element>
  <my-nested-element>second</my-nested-element>
</my-element>

<button>test</button>
Run Code Online (Sandbox Code Playgroud)

Sup*_*arp 5

为了检测通过元素从 Light DOM 插入的新元素<slot>,您可以在元素上或在 Shadow DOM 根本身上监听slotchange事件<slot>

请参阅下面的运行示例:

document.querySelector('button').onclick = () => 
  document.querySelector('my-element').insertAdjacentHTML('beforeend', '<my-nested-element>new addition</my-nested-element>');
  
Run Code Online (Sandbox Code Playgroud)
my-element,
my-nested-element {
  display: block;
}
Run Code Online (Sandbox Code Playgroud)
<script type="module">
  import {LitElement, html} from 'https://unpkg.com/@polymer/lit-element/lit-element.js?module';

  class MyElement extends LitElement {
    firstUpdated() {
      var shadow = this.shadowRoot
      var nb = shadow.querySelector( 'span#nb' )
      shadow.addEventListener( 'slotchange', () => 
        nb.textContent = this.querySelectorAll( 'my-nested-element').length 
      )    
    }
    render() {
      return html`<p>number of my-nested-element: <span id="nb"></span></p> 
                  <slot></slot>`;
    }  
  }
  customElements.define('my-element', MyElement);
</script>

<my-element>
  <my-nested-element>first</my-nested-element>
  <my-nested-element>second</my-nested-element>
</my-element>

<button>test</button>
Run Code Online (Sandbox Code Playgroud)