I am learning to use angular, CSS(tailwind), HTML, and typescript to build a website.
I click the menu button in the navbar 3 times but why was this.name
underdefined the first time the button was clicked?
How this.name
gets the HTML name the first time the menu button is clicked ? image
top-bar.component.ts
import { Component,OnInit } from "@angular/core";
@Component({
selector:'app-top-bar',
templateUrl:'./top-bar.component.html'
})
export class TopBarComponent implements OnInit {
constructor() {
}
ngOnInit() {
}
menu(e:any) {
console.log(e)
console.log(e.name)
let list:any = document.querySelector('#mobile-menu');
let menu_on:any = document.querySelector('#menu-on');
let menu_off:any = document.querySelector('#menu-off');
if (e.name == "menu") {
e.name = "close";
list.classList.remove('hidden');
menu_on.classList.add('hidden');
menu_off.classList.remove('hidden');
} else {
e.name = "menu";
list.classList.add('hidden');
menu_off.classList.add('hidden');
menu_on.classList.remove('hidden');
}
}
dropdown(e:any) {
let list:any = document.querySelector('#user-dropdown');
if (e.name == 'dropdown') {
e.name = "close";
list.classList.remove('hidden');
} else {
e.name = "dropdown";
list.classList.add('hidden');
}
}
}
top-bar.component.html
<nav >
<div >
<div >
<div >
<img src="https://tailwindui.com/img/logos/workflow-mark-indigo-500.svg" alt="Workflow">
</div>
<div >
<a href="" >Dashboard</a>
<a href="" >Team</a>
<a href="" >Projects</a>
<a href="" >Calendar</a>
<a href="" >Reports</a>
</div>
</div>
<div >
<div >
<div >
<button >
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9" />
</svg>
</button>
</div>
<div >
<button type="button" (click)="dropdown(this)" name="dropdown">
<img src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" alt="">
</button>
<div id="user-dropdown" >
<a href="" >Your Profile</a>
<a href="" >Settings</a>
<a href="" >Sign out</a>
</div>
</div>
</div>
</div>
<!-- button -->
<div >
<!-- ################# this line ################# -->
<button type="button" name="menu" (click)="menu(this)">
<!-- ################################## -->
<svg xmlns="http://www.w3.org/2000/svg" id='menu-on' fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" d="M4 6h16M4 12h16M4 18h16" />
</svg>
<svg xmlns="http://www.w3.org/2000/svg" id='menu-off' fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
</svg>
</button>
</div>
</div>
<!-- mobile menu -->
<div id="mobile-menu">
<div >
<a href="#" >Dashboard</a>
<a href="#" >Team</a>
<a href="#" >Projects</a>
<a href="#" >Calendar</a>
<a href="#" >Reports</a>
</div>
<div >
<div >
<img src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" alt="">
</div>
<div >
<div >Tom Cook</div>
<div >[email protected]</div>
</div>
<div >
<button >
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true">
<path stroke-linecap="round" stroke-linejoin="round" d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9" />
</svg>
</button>
</div>
</div>
<div >
<a href="#" >Your Profile</a>
<a href="#" >Setting</a>
<a href="#" >Sign out</a>
</div>
</div>
</nav>
CodePudding user response:
Instead of dropdown(this)
in template, you need to call dropdown($event)
. this
refers to the instance of the component here. And to retrieve the name
property you need to do e.target.name
in component method.
What is happening in your case is, in the first case when you log e
it logs the component instance itself and you assign something like e.name="dropdown"
so what you basically are doing is adding a property name
to the instance of that component dynamically which is not ideal.
And the other thing, using document.querySelector
is not ideal as either. You can use template reference variable using #
keyword in template and get the reference to that using ViewChild
in the component.