Home > front end >  How to use same shadow DOM on different places with different classes
How to use same shadow DOM on different places with different classes

Time:06-15

I'm using a pre-made web component called rssapp-feed. I want to use this in 2 different places one standard

Like this, this is what the original shadow DOM markup looks like:

enter image description here

and one with modifier class rssapp-feed--sidebar.

Like this:

enter image description here

I have added this modifier class through javascript.

var a = document.querySelector('rssapp-feed')
       .shadowRoot.querySelector('.rssapp-feed')
       .classList.add('rssapp-feed--sidebar');

The problem is I just want the modifier class to be added in one of the web components only. By adding a modifier class like this it's been adding on both the places. And by this whatever styles I give to modifier class it applies to both of those. Like if I want to set display: none to the last element with the class card-root it affects both the components.

Is there any way to use the same web component on two different places with different classes?

Here is the web component that I'm using in my HTML.

<rssapp-feed id="i0QRdHCkHgYPGNWs"></rssapp-feed><script src="https://widget.rss.app/v1/feed.js" type="text/javascript" async></script>

Here is the example on codeSandbox

Please any help would be appreciated.

CodePudding user response:

All you need is a better CSS selector to pass to the querySelector function. If you have control over the code where <rssapp-feed></rssapp-feed> is being added then simply add some unique class or data-* attribute to it. And then query using it.

Using class:

<rssapp-feed id="i0QRdHCkHgYPGNWs"></rssapp-feed>
 
<!-- Unique selector using class -->
<rssapp-feed id="i0QRdHCkHgYPGNWs" ></rssapp-feed>

In your JS code:

// Using class   element selector
document.querySelector('rssapp-feed.sidebar')
  .shadowRoot.querySelector('.rssapp-feed')
  .classList.add('rssapp-feed--sidebar');

Or using data-* attribute:

<rssapp-feed id="i0QRdHCkHgYPGNWs"></rssapp-feed>
 
<!-- Unique selector using data-* attribute -->
<rssapp-feed id="i0QRdHCkHgYPGNWs" data-id="sidebar"></rssapp-feed>

In your JS code:

// Using attribute selector
document.querySelector('rssapp-feed[data-id="sidebar"]')
  .shadowRoot.querySelector('.rssapp-feed')
  .classList.add('rssapp-feed--sidebar');

Finally, if you don't have control over the code, use some nested CSS selector using some parent which is unique to the web-component.

CodePudding user response:

You can extend any defined Web Component; and build your own Web Component on top of it:

Example: You can steal a 52 SVG playing cards Web Component with this Dev.to Post

<component-a>
 Hello Web Component A!
</component-a>

<component-b>
 Hello Web Component B!
</component-b>

<script>
  customElements.define('component-a', 
  class extends HTMLElement {
    constructor() { 
        super()
          .attachShadow({mode:'open'})
          .innerHTML=`<h1 style="color:red"><slot></slot></h1>`; 
    }
  });
  customElements.whenDefined('component-a').then(()=>{
    customElements.define('component-b', 
    class extends customElements.get("component-a") {
      connectedCallback(){
        if (super.connectedCallback) super.connectedCallback();
        this.shadowRoot.querySelector("h1").style.color = "green";
      }
    });
  })
</script>

  • Related