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.
We can create custom HTML elements, described by our class, with its own methods and properties, events and so on. Once a custom element is defined, we can use it on par with built-in HTML elements. That's great, as HTML dictionary is rich, but not infinite.
Custom tags are not valid in HTML5. But currently browsers are supporting to parse them and also you can use them using css. So if you want to use custom tags for current browsers then you can. But the support may be taken away once the browsers implement W3C standards strictly for parsing the HTML content.
Web Components consist of three separate technologies that are used together: Custom Elements. Quite simply, these are fully-valid HTML elements with custom templates, behaviors and tag names (e.g. <one-dialog> ) made with a set of JavaScript APIs. Custom Elements are defined in the HTML Living Standard specification.
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.
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].
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With