1

I'm trying to open my webcomponent in a new window (through a button click in an Angular app). The one that gets the closest to my desired result is this approach:

openPopup(): void {
    const popup = window.open('', '_blank', 'width=50');
    const component = document.createElement('component'); 
    popup.document.body.appendChild(component);
}

Note that I'm creating the element inside document and not in popup.document. This works, however, the svg images are not loaded correctly, probably because it created it in the other document..

Versus creating the element in the popup.document

openPopup(): void {
    const popup = window.open('', '_blank', 'width=50');
    const component = popup.document.createElement('component'); 
    popup.document.body.appendChild(component);
}

This last approach seems to be the one fitting the best but it simply does not give any HTML output except the HTML tag component. So it does not recognize the component for some reason in a new window.

What can I do?

er sd
  • 71
  • 1
  • 4

1 Answers1

1

Each window has its own DOM, thus each window has its own customElementsRegistry

When you open another window all required Custom Elements have to be (re)defined.

  function defineElement(root = window) {
    root.customElements.define('my-element', class extends root.HTMLElement {
      connectedCallback() {
        this.innerHTML = this.nodeName + ' defined; location: ' + root.location;
        console.log(root)
      }
    })
  }

Element in main DOM is created with: defineElement()

important part is: root.HTMLElement; each DOM must reference its own Base Classes.

Element in Popup is then created with reference to the popup window:

    const popup = window.open('', '_blank', 'width=200,height=100');
    popup.document.body.innerHTML = `<my-element>undefined in popup</my-element>`;
    defineElement(popup);

StackOverflow Snippet code doesn't play nice with window.open

Here is a JSFiddle: https://jsfiddle.net/WebComponents/f3tyng48/


You can ofcourse load Elements from one single JS file and reference that in every window

Things you can not do (yet?):

  • Query the Registry for all existing Elements
    If you know the inidividual element name you can use: CustomElementRegistry.get()

  • copy/clone Elements to another registry

Danny '365CSI' Engelman
  • 16,526
  • 2
  • 32
  • 49
  • See the [Notes on connectedCallback Browser issues](https://stackoverflow.com/questions/60838990/why-does-my-shadow-dom-break-my-custom-element/60844247#60844247). Adding content with HTML or ``append[Child](createElement)`` is the same as in main DOM. Standard JavaScript operations. React needs its own wrapper because React is oldskool and doesn't let you touch the DOM. Angular might need some extra work too. All these Frameworks will be become obsolete, just like jQuery became obsolete. – Danny '365CSI' Engelman Apr 07 '20 at 06:13