Javascript Icon Get 57% off the JavaScript Master Bundle!

See the bundle then add to cart and your discount is applied.

0 days
00 hours
00 mins
00 secs

Hacking SVG, traversing with ease - addClass, removeClass, toggleClass functions

Update: I’ve turned this into a small JavaScript module named Lunar and pushed to GitHub, please use that code instead as it doesn’t extend native DOM APIs and also has accompanying unit tests :)

I encountered how painful traversing inline SVG can be when working on a recent project, simple DOM APIs such as adding, removing and toggling classes just aren’t there, or supported by tools such as jQuery (yes, I even tried jQuery).

Inline SVG is SVG in the DOM, rendered from its XML. Here’s a quick look at example inline SVG which would sit anywhere in the DOM:

<svg id="svg" xmlns="" version="1.1" height="190">
  <circle cx="100" cy="50" r="40" fill="red" />

The svg element acts as a wrapper to the XML inside, whilst defining a few things such as height, width, namespace and version. You’ll notice I’ve added an id attribute, with the value of svg. Current DOM APIs make this seamlessly easy to target:

// grabs 
var mySVG = document.querySelector('#svg');

Problem: DOM stuff

But the problem begins when trying to do the ‘usual’ DOM stuff, adding a class, or removing a class. You’d think it would be pretty simple, but even using jQuery’s APIs don’t allow it to work either, so I wrote my own and I’m pretty pleased with its compactness. The trick is to set the attribute again, you can’t keep adding/removing classes using the .className method. The getAttribute method is what I’ve used to grab the class attribute’s value, and then the idea behind it is to grab that attribute, manipulate it and then set it back again.

JavaScript Array Methods eBook Cover

🎉 Download it free!

Ready to go beyond ForEach? Get confident with advanced methods - Reduce, Find, Filter, Every, Some and Map.

  • Green Tick Icon Fully understand how to manage JavaScript Data Structures with immutable operations
  • Green Tick Icon 31 pages of deep-dive syntax, real-world examples, tips and tricks
  • Green Tick Icon Write cleaner and better-structured programming logic within 3 hours

As an extra bonus, we'll also send you some extra goodies across a few extra emails.

Let’s say I have a function, I need to add a class to an SVG circle onclick:

// grabs 
var mySVG = document.querySelector('#svg circle');
mySVG.setAttribute('class', 'myClass');

… will give us:

  <svg id="svg" xmlns="" version="1.1" height="190">
  <circle cx="100" cy="50" r="40" fill="red" class="myClass" />

I have to think as the ‘class’ attribute as totally made up and that className doesn’t exist. And manipulating this is where the magic happens.

hasClass API

As with all the APIs, I’m hanging these off the SVGElement’s prototype constructor so all SVG nodes inherit the methods. With hasClass, I’m extending the native Object with a function. This method allows simple declaration of the APIs. Inside the hasClass function, I’m creating a new Regular Expression, which gets dynamically created through its className parameter and immediately tested against its attribute value. JavaScript’s .test() returns a boolean (true/false), a simple way to test a class presence.

SVGElement.prototype.hasClass = function (className) {
  return new RegExp('(\\s|^)' + className + '(\\s|$)').test(this.getAttribute('class'));

addClass API

Adding a class is simple, just set the attribute. Here I simply make a check using the hasClass API, and if it doesn’t exist I add it. There’s no point adding it again if it does exist. If it doesn’t exist, I set the attribute class with the current class value, plus my new class name, super simple.

SVGElement.prototype.addClass = function (className) {
  if (!this.hasClass(className)) {
    this.setAttribute('class', this.getAttribute('class') + ' ' + className);

removeClass API

Removing a class was the most fun, there’s also the issue of keeping spaces intact, for instances I had to work out how to remove a class and keep the appropriate spaces around that class name. You can see I create a new class here called removedClass, where I get the current value, then replace the passed in className using a dynamically created RegExp again. This RegExp has some coolness added to it, you’ll see I declare ‘g’ at the end of the RegExp declaration, this means global, and will replace all instances of the class, for example if it was declared more than once throughout the class value. I then make a safety check to ensure the class is there, and set the attribute back on the element.

You’ll also see I used a second parameter as well in the replace method, which says ‘$2’. This is a nifty little trick, which refers to the capture group in the RegExp. Capture groups are denoted by circular brackets, my example at the end of the RegExp says _’(\s $)’, this denotes a capture group, and then looks for whitespace after the className, OR it’s at the end of the string, which is what the _$ means. I can then remove the className and leave whatever was in the capture group, either a space or nothing, which keeps the class value tidy.
SVGElement.prototype.removeClass = function (className) {
  var removedClass = this.getAttribute('class').replace(new RegExp('(\\s|^)' + className + '(\\s|$)', 'g'), '$2');
  if (this.hasClass(className)) {
    this.setAttribute('class', removedClass);

toggleClass API

Toggling from hereon is super simple, I’ll check if the element has the class, and based on that I’ll either add or remove the class using the above APIs.

SVGElement.prototype.toggleClass = function (className) {
  if (this.hasClass(className)) {
  } else {


Usage is simple, and simple API style:

// Grab my Node
var mySVG = document.querySelector('#svg circle');

// hasClass

// addClass

// removeClass

// toggleClass

Thank you for reading!

Free eBooks:

JavaScript Array Methods eBook Cover

Ready to go beyond ForEach? Get confident with advanced methods - Reduce, Find, Filter, Every, Some and Map.

NestJS Build a RESTful CRUD API eBook Cover

Build your first NestJS app. With the CLI you'll learn the basics of real-world NestJS development.