在Web组件中引用轻量级DOM

时间:2017-06-30 16:21:43

标签: javascript dom web-component shadow-dom custom-element

我正在使用skate.js并尝试引用Web组件的轻量级DOM进行验证和操作。该组件如下所示:

<res-checkbox>
  <label slot="label">This is res-checkbox</label>
  <input slot="checkbox" type="checkbox" id="test-id" />
</res-checkbox>

我正在尝试引用该复选框以验证它是否存在并向其添加ID,以便shadow DOM标签可以使用for属性引用它。但是,在渲染组件后,我无法弄清楚如何引用它。

import { Component, h, define, prop } from 'skatejs';

export class ResComponent extends Component {

  static get is() { return 'res-checkbox'; }

  renderedCallback() {
    console.log(this.querySelector('input[type="checkbox]'));
    // -> null
    console.log(this.getElementsByTagName('input')[0]);
    // -> undefined
    console.log(this.shadowRoot.querySelector('input[type="checkbox]'));
    // -> null
    console.log(this.shadowRoot.getElementById('checkbox').querySelector('input'));
    // -> null
    console.log(this.shadowRoot.getElementById('checkbox').assignedNodes());
    // -> []
    console.log(this.childNodes[1]);
    // -> undefined
    console.log(this.children[1]);
    // -> undefined
  }

  renderCallback() {
    return <div id="wrap">
      <slot name="label" id="label"></slot>
      <label id="fakeCheckbox">
        <slot name="checkbox" id="checkbox"></slot>
      </label>
    </div>;
  }

}

define(ResComponent);

在Web组件中引用light DOM的最佳方法是什么?

1 个答案:

答案 0 :(得分:2)

由于light DOM只是普通的DOM,你可以照常引用其中的元素:

var input = this.querySelector('input[type="checkbox"]'))
var label = this.getElementsByTagName('label')[0]

如果您的示例不起作用,可能是因为方法renderedCallback()没有以正确的方式或在正确的时间调用。

以下是&#34; vanilla&#34;中的一个运行示例javascript(抱歉,我不知道SkateJS)

&#13;
&#13;
customElements.define('res-checkbox', class extends HTMLElement {
  constructor() {
    super()
    this.attachShadow({ mode: 'open' })
      .innerHTML = `<div id="wrap">
        <slot name="label" id="label"></slot>
        <label id="fakeCheckbox">
          <slot name="checkbox" id="checkbox"></slot>
        </label>
      </div>`
  }

  connectedCallback() {
    var input = this.querySelector('input[type="checkbox"]')
    var label = this.querySelector('label')
    console.log(input, label)
    label.setAttribute('for', input.id)
  }
})
&#13;
<res-checkbox>
  <label slot="label">This is res-checkbox</label>
  <input slot="checkbox" type="checkbox" id="test-id">
</res-checkbox>
&#13;
&#13;
&#13;