Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

298
Views
angular - Adding a class to a DOM element when clicked

I am trying to add a class that will change its appearance (e.g. burger to x), to a menu trigger DOM element that has its own method to show an overlay menu, but I can't figure out how to do it.

Here is what I have so far - this is calling an external method for the menu itself:

import { Component, ElementRef, ViewChild, Renderer, AfterViewInit } from '@angular/core';

import { LayoutService } from 'app/core/services/layout.service';

@Component({
    moduleId: module.id,
    selector: 'header-main',
    templateUrl: 'header-main.component.html',
})


export class HeaderMainComponent {

    @ViewChild('nav-trigger') el: ElementRef;

    constructor(private layoutService: LayoutService) { }

    menuToggle() {
        this.layoutService.mainMenuToggle();
        this.el.nativeElement.classList.add('opened');
    }
}

I am new to Angular 2. How is this supposed to work-out? Should I use the Renderer , why I should use the Renderer? And etc. questions


EDIT: The issue with the absolute click event (selecting the child, not the parent) is that we have to use a reference tag paired with the @ViewChild decorator as so:

@ViewChild('navTrigger') navTrigger: ElementRef; which relates to the #navTrigger reference in the HTML template.

Therefore:

export class HeaderMainComponent {
    logoAlt = 'We Craft beautiful websites'; // Logo alt and title texts

    @ViewChild('navTrigger') navTrigger: ElementRef;

    constructor(private layoutService: LayoutService, private renderer: Renderer) { }

    menuToggle(event: any) {
        this.layoutService.mainMenuToggle();
        this.renderer.setElementClass(this.navTrigger.nativeElement, 'opened', true);
    }
}
about 4 years ago · Santiago Trujillo
3 answers
Answer question

0

To accomplish what you want, you will need to use the Renderer(injecting it into the constructor with private renderer: Renderer). The Renderer provides an abstraction over native elements and provides a safe way to interact with the DOM.

In your template, you should be able to do something like this:

<div (click)="menuToggle($event)"></div>

This captures the click event and passes it to the menuToggle function.

Then in your component, you should be able to interact with the DOM using the Renderer like this:

menuToggle(event:any) {
    this.renderer.setElementClass(event.target,"opened",true);
}

The function signature for setElementClass, according to the docs is setElementClass(renderElement: any, className: string, isAdd: boolean) : void

For further reading on the Renderer, this is a good article on Medium. In talking about using the ViewChild and accessing the DOM through the nativeElement compared to using the Renderer, it says:

This works fine(using nativeElement from a ViewChild). We are grabbing the input element with the help of the ViewChild decorator and then access the native DOM element and call the focus() method on the input.

The problem with this approach is that when we access the native element directly we are giving up on Angular’s DOM abstraction and miss out on the opportunity to be able to execute also in none-DOM environments such as: native mobile, native desktop, web worker or server side rendering.

Remember that Angular is a platform, and the browser is just one option for where we can render our app.

Hope this helps.

about 4 years ago · Santiago Trujillo Report

0

Since Tyler's answer, things have changed a bit. Renderer is depreciated and replaced by Renderer2. In Renderer 2, the class setElementClass is replaced by addClass. And the new function signature for addClass, according to the docs is

addClass(el: any, name: string): void

So the updated menuToggle function should read

menuToggle(event:any) {
    this.renderer.addClass(event.target,"opened");
}
about 4 years ago · Santiago Trujillo Report

0

Create a backing field in the component then bind to ngClass and use a typescript expression to conditionally add the class to the element. Note a click event should be used to toggle the backing field. eg.

  1. In component: openedBool: boolean = false;
  2. And toggleOpenedBool() { openedBool = !openedBool; }
  3. In template: <div (click)="toggleOpenedBool()" [ngClass]="{'opened': openedBool}"></div>
about 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!