Can I access custom html tag <component> or <slot> contents

Sanborn picture Sanborn · Sep 22, 2016 · Viewed 7.4k times · Source

Let's say I want to create a custom html element such as:

<video-container>
  <video></video>
</video-container>

So I create a template like this:

<div class="wrapper">
   etc..
   <content></content>
</div>

Then I attach it to the page via an HTML Element Prototype createdCallback.

Inside that callback I want to be able to attach listeners to the video element so I can do stuff on play, pause etc.. It's not clear to me if there is anyway to access the video tag passed in. I can get access to the content tag but it doesn't show any child nodes. Is this possible?

I can access the video element if I just grab the whole document and get the video element but this is ugly because I want to be able to get only the video tag in the scope of the present custom element.

Answer

Supersharp picture Supersharp · Sep 22, 2016

Direct way

You should access it by using querySelector on the custom element itself:

VideoContainerPrototype.createdCallback = function ()
{
    var video1 = this.querySelector( 'video' ) 
}

You don't need to pass by the Shadow DOM.


Shadow way

But if you want to get it from the Shadow root you can use the assignedNodes() method on your <slot> element (formerly getDistributedNodes() on <content>):

var video2 = this.shadowRoot.querySelector( 'slot' ).assignedNodes()[1] 

It returns an Array of Nodes that were inserted. Because in your example there's a text Node at index [0] you'll have to get the Node at [1].

Note: You can also use named slots if you want to get your <video> element at index [0].