I want to make a drop-down menu and that when clicking on the input, the menu is displayed with a toggle that removes or places the 'hidden' class
I have this method
toggleMenu() {
this.classList.toggle("hidden");
}
And here the template.
render(){
return html`
<input @click="${this.toggleMenu}" type="button">
<ul class="hidden">
<slot></slot>
</ul>
`;
}
One straightforward solution is to add a property to your custom element, eg open
, that is toggled in your toggleMenu
method:
static get properties() {
return {
open: { type: Boolean },
};
}
constructor() {
super();
this.open = false;
}
toggleMenu() {
this.open = !this.open;
}
Then in your render
method set the <ul>
's class
attribute based on the value of this.open
:
render(){
return html`
<button @click=${this.toggleMenu} type="button">Toggle</button>
<ul class=${this.open ? '' : 'hidden'}>
<slot></slot>
</ul>
`;
}
You can see this working in the below snippet:
// import { LitElement, css, html } from 'lit-element'; const { LitElement, css, html } = litElement; class DropDownMenu extends LitElement { static get properties() { return { open: { type: Boolean }, }; } static get styles() { return css` ul.hidden { display: none; } `; } constructor() { super(); this.open = false; } toggleMenu() { this.open = !this.open; } render(){ return html` <button @click=${this.toggleMenu} type="button">Toggle</button> <ul class=${this.open ? '' : 'hidden'}> <slot></slot> </ul> `; } } customElements.define('drop-down-menu', DropDownMenu);
<script src="https://bundle.run/lit-element@2.2.1"></script> <drop-down-menu> <li>Item 1</li> <li>Item 2</li> </drop-down-menu>
If you want to apply additional classes to the <ul>
you'll want to look into the classMap
function as described in the LitElement docs .
Alternatively, you can add reflect: true
to the open
property declaration, which lets you show or hide the <ul>
using CSS alone, rather than setting its class
in render
:
static get properties() {
return {
open: {
type: Boolean,
reflect: true,
},
};
}
static get styles() {
return css`
ul {
display: none;
}
:host([open]) ul {
display: block;
}
`;
}
Here it is in a working snippet:
// import { LitElement, css, html } from 'lit-element'; const { LitElement, css, html } = litElement; class DropDownMenu extends LitElement { static get properties() { return { open: { type: Boolean, reflect: true, }, }; } static get styles() { return css` ul { display: none; } :host([open]) ul { display: block; } `; } constructor() { super(); this.open = false; } toggleMenu() { this.open = !this.open; } render(){ return html` <button @click=${this.toggleMenu} type="button">Toggle</button> <ul> <slot></slot> </ul> `; } } customElements.define('drop-down-menu', DropDownMenu);
<script src="https://bundle.run/lit-element@2.2.1"></script> <drop-down-menu> <li>Item 1</li> <li>Item 2</li> </drop-down-menu>
Both of these are common approaches and the best one for your application will depend on your use case and personal preferences.
I like to keep it simple, if you need a reference to the DOM node then pass the event to the function like the following:
toggleMenu(ev) {
ev.target.classList.toggle("hidden");
}
And for the render method
render(){
return html`
<input @click="${(ev)=>{this.toggleMenu(ev)}}" type="button">
<ul class="hidden">
<slot></slot>
</ul>
`;
}
And you're done
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.