The replacement of className in inline SVG is not permitted (Error: 'Cannot read property 'className.replace' of undefined')

I've hit a roadblock trying to manipulate classes within an SVG document to modify the rect elements. The code works smoothly on divs in an external document, but I've tried several other solutions as well – all listed below. I'm still relatively new to JavaScript, so any help is greatly appreciated!

HTML

<svg id="candleSVG" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 468.05 446.9">
<defs>
    <style></style>
</defs>
<g id="Layer_2" data-name="Layer 2">
    <g id="Слой_1" data-name="Слой 1">
        <rect onclick="currentSlide(1)" onmouseover="currentSlide(1)" class="cls cls-1" x="5" y="134.7" width="56.5" height="156.6"/>
        <line class="cls-2" x1="33.25" y1="134.7" x2="33.25" y2="46.1"/>
        <line class="cls-2" x1="33.25" y1="291.3" x2="33.25" y2="434.7"/>
        <line class="cls-2" x1="165.65" y1="93.6" x2="165.65" y2="5"/>
        <line class="cls-2" x1="165.65" y1="267.4" x2="165.65" y2="384.8"/>

        <rect onclick="currentSlide(2)" onmouseover="currentSlide(2)" class="cls cls-3" x="137.45" y="93.6" width="56.5" height="209.1"/>
        <line class="cls-2" x1="298.85" y1="221.6" x2="298.85" y2="62.2"/>
        <line class="cls-2" x1="298.85" y1="324.5" x2="298.85" y2="441.9"/>

        <rect onclick="currentSlide(4)" onmouseover="currentSlide(4)" class="cls cls-4" x="406.55" y="104.7" width="56.5" height="155.1"/>
        <line class="cls-2" x1="434.85" y1="104.7" x2="434.85" y2="16.1"/>
        <line class="cls-2" x1="434.85" y1="259.8" x2="434.85" y2="374.1"/>

        <rect onclick="currentSlide(3)" onmouseover="currentSlide(3)" class="cls cls-5" x="270.65" y="182.8" width="56.5" height="177"/>
    </g>
</g>
</svg>
<div class="cls-slide">
    <h2>TEST 1</h2>
    <p></p>
</div>

<div class="cls-slide">
    <h2>TEST 2</h2>
    <p></p>
</div>

<div class="cls-slide">
    <h2>TEST 3</h2>
    <p></p>
</div>

<div class="cls-slide">
    <h2>TEST 4</h2>
    <p></p>
</div>

CSS

/* CANDLE STICK SVG */

.cls-1 {
fill:#9b0808;
}
.cls-1, .cls-2, .cls-3, .cls-4, .cls-5 {
stroke:#0c110b;
stroke-linecap:round;
stroke-linejoin:round;
stroke-width:10px;
}
.cls-1, .cls-3, .cls-4, .cls-5 {
cursor: pointer;
}
.cls-2 {
fill:none;
}
.cls-3 {
fill:#e81010;
}
.cls-4 {
fill:#4bd227;
}
.cls-5 {
fill:#1d6b0a;
}

.active, .cls:hover {
fill: #78f754;
}

.cls-slide {
display: none;
}

JS(TEST 1)

var slideIndex = 1;
showSlides(slideIndex);

function currentSlide(n) {
showSlides(slideIndex = n);
}

function showSlides(n) {
var i;
var slides = document.getElementsByClassName("cls-slide");
var candleSVG = document.getElementById("candleSVG").contentDocument;
var candles = candleSVG.getElementsByClassName("cls");

if (n > slides.length) {slideIndex = 1}
if (n < 1) {slideIndex = slides.length}
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
for (i = 0; i < candles.length; i++) {
candles[i].className = candles[i].className.replace(" active", "");
}
slides[slideIndex-1].style.display = "block";
candles[slideIndex-1].className += " active";
}

JS(TEST 2)

window.addEventListener("load", function showSlides(n) {

var slideIndex = 1;
showSlides(slideIndex);

var i;
var slides = document.getElementsByClassName("cls-slide");
var candleSVG = document.getElementById("candleSVG").contentDocument;
var candles = candleSVG.getElementsByClassName("cls");

if (n > slides.length) {slideIndex = 1}
if (n < 1) {slideIndex = slides.length}
for (i = 0; i < slides.length; i++) {
slides[i].style.display = "none";
}
for (i = 0; i < candles.length; i++) {
candles[i].className = candles[i].className.replace(" active", "");
}
slides[slideIndex-1].style.display = "block";
candles[slideIndex-1].className += " active";
});

function currentSlide(n) {
showSlides(slideIndex = n);
}

Answer №1

When dealing with SVG, the className property behaves differently compared to HTML. In SVG, it is an SVGAnimatedString rather than a simple DOMString like in HTML. This extra layer of abstraction was added in order to support SMIL animations.

If you need to manipulate the className in SVG, your code should look something like this...

candles[i].className.baseVal = ...

So, whenever you refer to className in your SVG code, remember to add .baseVal at the end.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is there a way to seamlessly update a field without refreshing the page or overloading the server?

I'm intrigued by the concept of updating a field dynamically without refreshing the page or overwhelming the server with queries. Stackoverflow demonstrates this feature when someone answers our question, and it instantly shows at the top of the page. ...

Is there a way to use Regex to strip the Authorization header from the logging output

After a recent discovery, I have come to realize that we are inadvertently logging the Authorization headers in our production log drain. Here is an example of what the output looks like: {"response":{"status":"rejected",&quo ...

Controlling the Alignment of HTML Div Elements

I'm struggling to align some of these divs, especially centering them. I want the page to closely resemble this image: Here are the specific requirements: 1) The header text should be centered vertically and placed in a separate div with a black back ...

Retrieving text data from the JSON response received from the Aeris API

I am attempting to showcase the word "General" text on the HTML page using data from the API found under details.risk.type. The JSON Response Is As Follows... { "success": true, "error": null, "response": [ ...

Does the [data-empty] constitute a component of the browser environment?

While exploring a node.js project that employs socket.io, I came across a piece of code that verifies whether the length of $('[data-empty]') is larger than 0. There was no class or ID associated with it, but it seemed like data-empty was some ki ...

Enhancing Website Design with Image Borders

I'm currently designing a website for a Media Agency and I'm looking to add a Frame-style border that gives the impression of being placed inside a television. The Television Image I have is a PNG file with a solid outer frame and a transparent i ...

Creating an installation package for an Electron application on Windows

Is it possible to create a Mac installer for an Electron app using a Windows PC? I have tried running npm make, but it only generates a Windows installer. ...

The stick division shows some bouncy behavior when seen on a mobile device

When viewing on mobile, the #main-categories div seems to be jumping instead of smoothly sticking to the top. What could be causing this behavior? Here is the code snippet I have: var s = $("#main-categories"); var pos = s.position(); $(window).scroll(f ...

Obtaining the value of an input field in HTML

I am currently working on a text input field that triggers a JavaScript function when a numeric value is entered. <input type="text" value="key" ng-keypress="submit(key)" ng-model="pager.page"/> Controller $scope.submit = function (val) { ...

Guide to simulating Twilio with Jest and TypeScript to perform unit testing

Please assist me in mocking a Twilio service that sends messages using Jest to mock the service. Below is the code I am working with: import { SQSEvent } from "aws-lambda"; import { GetSecretValueResponse } from "aws-sdk/clients/secretsmanag ...

Ending a Firestore `get` query upon unmounting component

Currently, I am retrieving data from Firestore in the componentDidMount function. However, if I happen to change the component while it is still in the process of fetching data, an error occurs: Warning: Can't call setState (or forceUpdate) on an u ...

Passing data from a parent node to a child node using JavaScript and the D3.js library

Creating a legend (var legend) for my d3js chart involves binding data to the parent 'g' element, specifically a string (label) that is needed in the child 'text' element. Any ideas on how to assign the parent data from the 'g&apo ...

Display of CSS color choices organized by row input

Is it feasible to dynamically color each table row based on the input in a designated column for that row? For example: B1 = 1 // Red row B2 = 1 // Red row B3 = 3 // Blue row B4 = 2 // Green row B5 = 1 // Red row And so forth? The datatable wi ...

Avoiding multiple ajax requests due to multiple clicks

I have a blog on WordPress that has a jQuery code allowing users to click a bookmark link to save the post as a bookmark. Each post displays a total bookmark counter in this format: "Bookmarked (5)". The issue is that when a user clicks multiple times on t ...

Tips for updating the content within an HTML tag with jQuery

I am looking to update the parameter value of an applet tag based on the selection from a dropdown menu. As I am new to jQuery, I would appreciate any guidance on how to achieve this using jQuery. This is my current applet code: <applet id="decisiontr ...

Activate the b-form-file function by selecting the b-button

Working with BootstrapVue, I am trying to trigger my b-form-file after clicking on a b-button for style reasons. Additionally, I want the b-form-file to be hidden so it is not visible. I attempted the following approach, but it did not work for me: <b- ...

The custom error page in NextJS is failing to display

In my custom pages/404.ts file, I have coded the following: export default function NotFound() { return <h1>404 - Page Not Found</h1> } Additionally, there is another page that displays a 404 error when the organization is null: import Error ...

Can you explain Node.js and its applications as well as how it is commonly used?

A while back, during my time at IBM when I was immersed in learning, I came across something known as BlueMix, a cloud product. Within BlueMix, there was a rather primitive component called Node.js. Since that moment, I've been filled with curiosity a ...

Tips for adjusting the height of MUI Date Picker to fit your preferences

<Box sx={{ m: 1 }}> <LocalizationProvider dateAdapter={AdapterDayjs}> <DatePicker label="Enter Date" slotProps={{ textField: { height: "10px" } }} ...

Node.js utilized for conducting anti-virus scans on server-bound files prior to uploading

Is there a way for me to scan files that are submitted as request payloads to check if they contain potential viruses? For example, if someone tries to upload a txt file with the EICAR virus signature, I want to be able to scan it and reject it if it is in ...