1

Recently I saw following html DOM:

enter image description here

Please see the console output that queries the element display-1 and tells me that it's parentNode is a document-fragment. How can this happen? I read trough several articles and everyone stated that after appending the document fragment to a DOM element, the document-fragment remains as empty node and it's children are attached normally into the DOM.

I tried to create this situation by using shadow dom, custom elements, and so on. But nothing lead me to exactly this behaviour.

I tried it in chrome and edge.

Hopefully anyone can give me a hint. I struggle with this problem since yesterday...

Josef Biehler
  • 952
  • 4
  • 16

1 Answers1

0

I don't claim to be an expert on this, but I think at least part of the explanation is something along these lines: lightning web components uses a polyfill to implement a structure that is like a closed Shadow DOM (but isn't actually a native browser Shadow DOM). They use document-fragments in the implementation as well.

Documents with more info:

https://developer.salesforce.com/docs/component-library/documentation/lwc/lwc.create_dom https://lwc.dev/guide/composition#shadow-dom https://salesforce.stackexchange.com/questions/243725/understanding-shadow-dom-in-lightning-web-components

https://developer.salesforce.com/docs/component-library/documentation/lwc/lwc.testing_dom_api

In the last article, I think this quote gets more directly at how the document-fragment is a part of LWC.

"The article has a screenshot that shows DOM elements in Chrome Developer Tools. The screenshot shows a #shadow-root document fragment, which is the top node of a component’s shadow tree. If you look at a Lightning web component in Chrome Developer Tools, you don’t see the #shadow-root because LWC uses a shadow DOM polyfill. Salesforce supports some browsers that don’t implement the Shadow DOM web standard. The polyfill provides a shadow DOM in these browsers. To find Lightning web components on the page, look for element names that contain a hyphen. Select the element and run $0.shadowRoot in the Console. A Lightning web component returns #document-fragment."

So what salesforce says you need to do to select an element within one of their LWCs is to first select the entire component, then chain .shadowRoot (returns a document-fragment), then select elements within that. I have done this in a site built with LWCs just like this: document.querySelector('c-lb-header.cLB_Theme').shadowRoot.querySelector('#search-1')

I think there are other ways you can come across these document-fragments while traversing the DOM, like apparently .parentNode in your example is one. But even other ways... I can't remember where I read about another now. I imagine this is where problems can arise. And I'm sure other web pages may use document-fragments in ways where this could happen. I just only know about LWCs.

One thing I don't like about most of this documentation is that there are really two concepts at play here. One is a native browser shadow DOM, and the other is a more general concept of a shadow DOM for encapsulation (what SF implements with their polyfill and document-fragments and what not). But I don't think SF does a good job at distinguishing between these, so it can be even more confusing.

Someone more experienced can also probably take all this documentation in and come up with a more specific and precise answer to your question. I still don't really get how LWCs document-fragments appear to be attached to the DOM, but still behaving as if they are inaccessible. It may also have to do with the SF "Locker service", but I really don't know about that yet. https://developer.salesforce.com/docs/component-library/tools/locker-service-viewer

Ammon
  • 31
  • 2