Amy Yuanyuan Chen
Amy Yuanyuan Chen

Reputation: 33

How to Shadow DOM, if I want to perserve event from outside, but prevent custom event bubbling

I am trying to use Shadow DOM to encapsulate custom event bubbling but still get the styles from outside.

So what I want to achieve is that ...

Is there a way that I can achieve all three above? Thank you very much!

var outer = document.getElementById('outer'); 
var shadowroot = outer.attachShadow({mode: 'open'});

shadowroot.innerHTML = `
  <slot></slot>
`; 

var spanInsideShadow = document.getElementById('span_inside_shadow'); 
shadowroot.appendChild(spanInsideShadow); 

var spanInLightDom = document.getElementById('span_in_slot'); 

spanInsideShadow.addEventListener('click', function(e){
  spanInsideShadow.dispatchEvent(new Event('span-clicked', {bubbles: true}));
}); 


outer.addEventListener('span-clicked', function(e){
  console.log('outer received custom event. Do not want this!'); 
}); 

outer.addEventListener('click', function(e){
  console.log('click event received, source elem = ', e.srcElement); 
});
span {
  color: red;
}
<div id='outer'>
  <div id='inner'>
    <span id='span_light_dom'> SPAN_IN_LIGHT_DOM_BUT_RENDERED_IN_SLOT </span>
  </div>
</div>

<div>
<span id='span_normal'>A_NORMAL_SPAN_OUTSIDE </span>
</div>

<div>
<span id='span_inside_shadow'>SPAN_WILL_BE_APPENDED_TO_SHAODOW_ROOT</span>
</div>

I hope I am explaining myself clear enough. Thank you very much for your help!

Upvotes: 2

Views: 1131

Answers (1)

Intervalia
Intervalia

Reputation: 10965

The only way to auto-convert your event target and to get outside styles into Shadow DOM is to include all of the DOM and the CSS in the Shadow DOM. And not by using <slot>.

If you are loading an external CSS file through the <link> tag then you can include that same <link> tag in your shadow DOM.

If you are including a <style> tag in your main page then you need to include a clone of that <style> tag inside your shadow DOM.

As I write this, the only other option you have is to use CSS variables that will allow the outside world to change values of the inner CSS. But then you have to write your CSS to use variables.

No matter which way you chose you can only affect the styling of elements within the Shadow DOM if you copy those styles in or affect them through CSS variables. If you don't include some new, unexpected, CSS then it will not be applied.

And since you want the Shadow DOM to convert the target of your events you must place the DOM inside the shadow and not by using <slot>.

There are other methods being worked on, but those won't be out for some time. Probably several years.

I hope this answers your question. Unfortunately I don't think this is what you wanted to find out.

Upvotes: 1

Related Questions