import { Component, Prop } from '@stencil/core';
@Component({
tag: 'my-component',
styleUrl: 'my-component.css',
shadow: true
})
export class MyComponent {
@Prop() first: string;
@Prop() last: string;
getElementHere() {
// how can I get the div here?
}
render() {
return (
<div>
Hello, World! I'm {this.first} {this.last}
</div>
);
}
}
I want to get the DOM element just like in native JS. How do you do this in Stencil? getElementById does not work.
Stencil components are created by adding a new file with a . tsx extension, such as my-first-component. tsx , and placing them in the src/components directory.
One is a template syntax (JSX) and the other is a renderer (VDom). Stencil uses a much smaller and highly optimized VDom, but “how” the renderer works and improvements to be made are behind JSX.
Stencil is a simple compiler for generating Web Components. The webpack plugin allows apps to easily import components using the webpack bundler. The plugin is for apps with build scripts already using a traditional webpack toolchain.
<Host> is a virtual component, a virtual API exposed by stencil to declaratively set the attributes of the host element, it will never be rendered in the DOM, i.e. you will never see <Host> in Chrome Dev Tools for instance.
To expand on Fernando's answer, the @Element decorator binds the component's root element to this property. It's important to note a few properties of this approach:
componentDidLoad)..querySelector(...) or .querySelectorAll(...) methods to retrieve and manipulate them.Here is an example showing when the element is accessible, and how to manipulate nodes within this element (correct as of stencil 0.7.24):
import { Component, Element } from '@stencil/core';
@Component({
tag: 'my-component'
})
export class MyComponent {
@Element() private element: HTMLElement;
private data: string[];
constructor() {
this.data = ['one', 'two', 'three', 'four'];
console.log(this.element); // outputs undefined
}
// child elements will only exist once the component has finished loading
componentDidLoad() {
console.log(this.element); // outputs HTMLElement <my-component ...
// loop over NodeList as per https://css-tricks.com/snippets/javascript/loop-queryselectorall-matches/
const list = this.element.querySelectorAll('li.my-list');
[].forEach.call(list, li => li.style.color = 'red');
}
render() {
return (
<div class="my-component">
<ul class="my-list">
{ this.data.map(count => <li>{count}</li>)}
</ul>
</div>
);
}
}
From the official docs
In cases where you need to get a direct reference to an element, like you would normally do with document.querySelector, you might want to use a ref in JSX.
So in your case:
import { Component, Prop } from '@stencil/core';
@Component({
tag: 'my-component',
styleUrl: 'my-component.css',
shadow: true
})
export class MyComponent {
@Prop() first: string;
@Prop() last: string;
divElement!: HTMLElement; // define a variable for html element
getElementHere() {
this.divElement // this will refer to your <div> element
}
render() {
return (
<div ref={(el) => this.divElement= el as HTMLElement}> // add a ref here
Hello, World! I'm {this.first} {this.last}
</div>
);
}
}
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