Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Web Components: how to access a slotted element using shadowRoot.querySelector

Hi I am new to Web Components concept. I wanted to know if we can access a slotted element using shadowRoot.querySelector

I have implemented an input field as slot for setting some values dynamically. And have a class added to it 'column-title'. I am trying to access this element in connectedCallback() like this

var titleInput = this.shadowRoot.querySelector('.column-title')

But it returns null.

Please help.

like image 384
Treesa Avatar asked Feb 24 '19 04:02

Treesa


People also ask

What is element shadowRoot?

The element that the tree is attached to (<my-header>) is called the shadow host and the host has a property called shadowRoot that refers to the shadow root. The shadow root is a document fragment that is attached to the host element and it has a host property that identifies its host element.

What is slot in web component?

<slot>: The Web Component Slot element The <slot> HTML element—part of the Web Components technology suite—is a placeholder inside a web component that you can fill with your own markup, which lets you create separate DOM trees and present them together.

Which selector can work for shadow DOM elements?

There's no selector that can directly affect shadow DOM styles from the document. But just as we expose methods to interact with our component, we can expose CSS variables (custom CSS properties) to style it. Custom CSS properties exist on all levels, both in light and shadow.


1 Answers

I'm not sure what the issue is, but you should be able to get a slot using querySelector and its class. I've mocked up an example below.

The console will print out references to the slot. If you're attaching a class just for the purpose of finding the slot then it's probably better to set an id (assuming that it's within a shadow root) and find it with this.shadowRoot.getElementById('my-slot-id')

customElements.define('blue-box',
  class extends HTMLElement {
    constructor() {
      super();
      var template = document
        .getElementById('blue-box')
        .content;
      const shadowRoot = this.attachShadow({
          mode: 'open'
        })
        .appendChild(template.cloneNode(true));
    }
    
    connectedCallback() {
    	console.log(this.shadowRoot.querySelector('slot.target-slot'));
    }
  });
<template id="blue-box">
  <style>
  .blue-border {
    border: 2px solid blue;
    padding: 5px;
    margin: 5px;
  }
  </style>
  <div class='blue-border'>
    <slot name='interior' class='target-slot'>NEED INTERIOR</slot>
  </div>
</template>

<blue-box>
  <span slot='interior'>My interior text</span>
</blue-box>
<blue-box>
  <span slot='interior'>
  Check Here: <input type='checkbox'>
  </span>
</blue-box>
like image 66
rovyko Avatar answered Sep 28 '22 18:09

rovyko