2

I'm in the middle of developing custom elements for basic reusable controls (e.g. buttons, menus, data tables etc.) I'm aware of the browser support for custom elements and shadow DOMs, but I'm doing good with the available polyfills in general.

For some custom elements I use third-party scripts for extra functionality but sometimes they don't work as intended when they have to manipulate the DOM in some way.

That happens every time an external script wants to search for an element by class or id. Obviously the call

document.getElementById (id)

or

document.getElementsByClassName (class)

doesn't work because the element with the id or class cannot be found in the global DOM but in the shadow DOM.

As far as I know, you can't give the document variable a new reference in javascript.

So, is there a solution to this problem without parsing the whole script and rewriting it to become usable in a shadow DOM context?

EDIT: It's not about getting elements from shadow DOMs in general but how 3rd-party scripts can be used that don't know that they have to search in the shadow DOM they are called from and not in the main DOM. As pointed out in the comments by CBroe.

Supersharp
  • 29,002
  • 9
  • 92
  • 134
sdrecker
  • 45
  • 7
  • Possible duplicate of [How to get element in shadow root with JavaScript?](https://stackoverflow.com/questions/38701803/how-to-get-element-in-shadow-root-with-javascript) – Protozoid Jun 06 '18 at 10:05
  • @Protozoid not really a duplicate IMHO; over there it’s about how to get access to elements inside the shadow DOM using code written specifically for this purpose, but the question here is primarily how to handle 3rd-party scripts, that weren’t written with “shadow DOM capability” in mind. – CBroe Jun 06 '18 at 10:07
  • 1
    @CBroe Fair ... Perhaps this discussion will help https://stackoverflow.com/questions/45917672/what-are-the-drawbacks-of-using-shadow-dom It's suggesting that ShadowDOM is not the appropriate approach when requiring 3rd party libraries pluggability – Protozoid Jun 06 '18 at 10:09
  • @Protozoid yeah, I could agree to that somewhat. One of the main purposes of shadow DOM _is_ isolation from “the rest”, so stuffing that with 3rd-party libraries might kinda defeat the point to begin with. – CBroe Jun 06 '18 at 10:21
  • What 3rd party scripts are you trying to use? https://stackoverflow.com/questions/50698021/using-external-js-libraries-in-a-web-component/50750294#50750294 – Intervalia Jun 07 '18 at 21:25

1 Answers1

4

A workaround is to pull the element the 3rd party library needs to catch out of the Shadow DOM.

<your-element>
  <div id="visible-id" class="visible-class"></div>
</your-element>

And insert it in the Shadow DOM using the <slot> element.

Note: I've used a direct, HTML, example but you can insert the callable element by script when your custom element is created:

connectedCallback () {
    this.innerHTML = '<div id="visible-id"></div>'
}  

Of course it's not really in the Shadow DOM but it will work with most of the 3rd-party libraries.

You could also choose not to use Shadow DOM at all depending on your needs.

Supersharp
  • 29,002
  • 9
  • 92
  • 134
  • Very good advise! But I'm not sure after reading about slots, if this is possible:
    (Because of the duplicate IDs)
    – sdrecker Jun 06 '18 at 20:16
  • it will depend how the 3rd-party lib you use will handle multiple instance: you can either give 2 different id/class name or not. it's not related to slots but to the library behavior – Supersharp Jun 06 '18 at 23:19
  • Okay I tried it, and it works. Even if the underlying structure of the custom element is not in the shadow DOM anymore, I still enjoy the fact, that I just have to add my custom element to the DOM and have all functionality under the hood. So, thank you very much! – sdrecker Jun 08 '18 at 08:06