Предоставьте доступ к элементу веб-компонента из ShadowDom для внешнего JS с помощью document.getElementById - PullRequest
0 голосов
/ 07 ноября 2018

Я работаю с текущим шаблоном стартового комплекта PWA от Polymer.

https://github.com/Polymer/pwa-starter-kit/tree/template-typescript

Моя страница элемента веб-компонента возвращает следующий код с элементом DIV:

return html`
      ${SharedStyles}    
      <section>
        ...my content...

      </section>
      <div id="CONTAINER NAME"></div>
    `

Мне нужно получить доступ к элементу ИМЯ КОНТЕЙНЕРА из внешнего javascript через document.getElementById. Я знаю, что он сидит в тени, но я не могу изменить внешний JS. Так что вопрос в том, как сделать его доступным из JS через document.getElementById?

Внешний JavaScript загружает iframe в именованный div. Этот внешний компонент должен получить элемент div на document.getElementById, чтобы загрузить iframe в указанный div.

Я искал и не нашел способа заставить элемент div из теневого домена моей страницы веб-компонента быть выставленным / помещенным в DOM.

Я только что нашел это решение, упомянутое здесь, но я не заставил его работать в шаблоне PWA. Может быть, так как теневые домы каскадируются в шаблоне PWA?

https://stackoverflow.com/a/47082470/9192527

Можно ли каким-либо образом обновить веб-компонент на основе набора Polymer v3 / PWA с помощью внешнего javascript (стороннего производителя), все еще использующего document.getElementbyId для изменения моего div внутри веб-компонента?

Итак, ищите возможность, используя, возможно, slots, чтобы выставить элемент теневого дома на светлый дом? Но я не могу заставить его работать с решениями, указанными выше.

Ответы [ 2 ]

0 голосов
/ 07 ноября 2018

Итак, вы ищете возможность, используя, возможно, слоты, чтобы выставить элемент теневого дома на светлый дом? Но не могу заставить его работать с решениями, связанными выше.

На самом деле то, что вы должны сделать, это наоборот: выставить <div> для выбора в светлом DOM и интегрировать его в Shadow DOM через тег <slot>, если вам нужно.

this.innerHTML = '<div id="CONTAINER NAME"></div>'
return html`
      ${SharedStyles}    
      <section>
        ...my content...

      </section>
      <slot></slot>
    `
0 голосов
/ 07 ноября 2018

Как вы упомянули, lit-element по умолчанию использует shadow dom, поскольку имеет много преимуществ при создании компонентов многократного использования.

Тем не менее, вы можете отказаться от него и использовать «легкий» dom, который будет отображать содержимое компонента в главном dom, что, в свою очередь, сделает этот контент доступным с помощью таких вещей, как document.getElementById() или document.querySelector()

Вот минимальный пример того, как использовать light dom в компоненте на основе освещенных элементов (а вот глюк , где вы можете увидеть его в действии)

class MyElement extends LitElement {  
  render() {
    return html`
      <section>
        ... My content ...
      </section>
      <div id="myElementContainer">
        This is a container inside my element
      </div>
    `;
  }

  createRenderRoot() {
    // this is what overrides lit-element's behavior so that the contents don't render in shadow dom
    return this;
  }

}

Только помните, что в этом случае вы должны использовать этот компонент только один раз в своем приложении из-за того, как работает getElementById(), и что вы не сможете использовать <slot> в своем компоненте, поскольку это только функция, доступная для тени дом

...