JavaScript allows for the dynamic addition of foreign objects to an SVG

After running this code initially, it displays a blank screen, but when I make updates using the developer tool in Chrome, the data appears. Can someone provide an explanation as to why this happens? Could it be related to the DOM running again in the browser, and if so, why does it not display correctly the first time? Is there a connection to the presence of foreignObject?

<!DOCTYPE html>

<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title></title>
    </head>
    <body>
    <svg id="t">
    <g>
        <text x="10" y="10">hello</text>
    </g>
    </svg>
        <script>
            var s = document.getElementById('t');
            var g = s.childNodes[1];
            console.log(g.childNodes[1].remove());
            var foreign = document.createElementNS('http://www.w3.org/2000/svg',"foreignObject");

            foreign.setAttribute('width', 500);
            foreign.setAttribute('height', 150);
            var txt = document.createElementNS('http://www.w3.org/2000/svg', 'text');
            txt.setAttribute('x', '10');
            txt.setAttribute('y', '10');
            var t = document.createTextNode("This is a paragraph.");
            txt.appendChild(t);
            foreign.appendChild(txt);
            g.appendChild(foreign);

 </script>        
</body>
</html>

Answer №1

@JabranSaeed, if you are looking to incorporate foreign objects into your project, it is recommended to follow this approach:

<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title></title>
    </head>
    <body>
    <svg id="t">
    <g>

    </g>
    </svg>
<script>
  var svgElement = document.getElementById('t');
        var group = svgElement.childNodes[1];

        var foreignObject = document.createElementNS

('http://www.w3.org/2000/svg',"foreignObject");

        foreignObject.setAttribute('width', 500);
        foreignObject.setAttribute('height',500);
        var innerDiv = document.createElement('div');
        var textNode = document.createTextNode("xxxx");
        innerDiv.appendChild(textNode);
        foreignObject.appendChild(innerDiv);

        group.appendChild(foreignObject);
</script>
</body>
</html>

Answer №2

It is important to note that an svg text node cannot be the child of a foreignObject node directly. Instead, you need to create an svg node first and then append the text node as a child of the svg node. Here is an example:

        var s = document.getElementById('t');
        var g = s.childNodes[1];
        console.log(g.childNodes[1].remove());
        var foreign = document.createElementNS('http://www.w3.org/2000/svg',"foreignObject");

        foreign.setAttribute('width', 500);
        foreign.setAttribute('height', 150);
        var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
        var txt = document.createElementNS('http://www.w3.org/2000/svg', 'text');
        txt.setAttribute('x', '10');
        txt.setAttribute('y', '30');
        var t = document.createTextNode("This is a paragraph.");
        txt.appendChild(t);
        foreign.appendChild(svg);
        svg.appendChild(txt);
        g.appendChild(foreign);
<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title></title>
    </head>
    <body>
    <svg id="t">
    <g>
        <text x="10" y="30">hello</text>
    </g>
    </svg>
</body>
</html>

It is worth mentioning that foreignObject should only be used if you need to create non-svg nodes. Additionally, when creating SVG elements, make sure to place them in the correct namespace, which is http://www.w3.org/2000/svg.

If you are encountering issues, try rerunning the code as sometimes Chrome may handle the creation of the svg parent node differently or it could be a bug in Chrome itself.

Answer №3

@JabranSaeed if you are looking to utilize foreignObject for inserting non-SVG elements, you can do so by following these steps:

<html lang="en">
    <head>
        <meta charset="utf-8" />
        <title></title>
    </head>
    <body>
    <svg id="t">
    <g>

    </g>
    </svg>
<script>
  var svg = document.getElementById('t');
        var group = svg.childNodes[1];

        var foreign = document.createElementNS

('http://www.w3.org/2000/svg',"foreignObject");

        foreign.setAttribute('width', 500);
        foreign.setAttribute('height',500);
        var innerDiv = document.createElement('div');
        var text = document.createTextNode("This is a paragraph.");
        innerDiv.appendChild(text);
        foreign.appendChild(innerDiv);

        group.appendChild(foreign);
</script>
</body>
</html>

Answer №4

It seems like the issue lies in the way you are appending the child element.

The order in which you are appending it may not be correct.

Take a look at the revised code snippet below and give it a try:

var s = document.getElementById('t');
var g = s.childNodes[1];
g.childNodes[1].remove();
var foreign = document.createElementNS('http://www.w3.org/2000/svg',"foreignObject");
foreign.setAttribute('width', 500);
foreign.setAttribute('height', 150);
var t = document.createTextNode("This is a paragraph.");
foreign.appendChild(t);
g.appendChild(foreign);

Please test the updated code and let me know if it resolves the issue.

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

Styling a dynamically-injected div using an AJAX request (xhrGet)

Hello everyone, currently I am using the code below to fetch updated content after receiving a "push" event from a server. The new content is then used to replace the existing div/content. However, I'm facing an issue where none of my styles from the ...

Jquery unresponsive in AJAX form output presentation

I recently delved into the world of jquery and AJAX, and while I grasp most concepts, I'm struggling with a small code snippet. On my webpage, there is a summary of articles. Clicking on an article name triggers a popup window with detailed informati ...

What is the best way to efficiently handle onChange events for multiple input checkboxes in Reactjs?

When I attempt to assign an onChange event listener to a group of checkboxes, clicking on one checkbox results in all checkboxes being clicked and the conditional inline styles that I defined are applied to all of them. Here is the JSX code snippet: class ...

Implementing a dynamic update of an HTML element's content with JSON data - Learn how!

My task involves creating a quiz application where I need to show the answers along with images of the choices stored in my JSON data. However, I encounter an error: Uncaught TypeError: Cannot set properties of null (setting 'src') when I attempt ...

The play button on the iOS video player will be deactivated automatically after watching 15 videos

I have developed an application using the Ionic Framework that includes multiple videos for playback. To organize these videos, I created a category system where users can click on a video title to access the corresponding video player page. The video pla ...

Is the memory usage of node.js proportional to the number of concurrent requests, or is there a potential memory leak?

Running the following node.js code: var http = require('http'); http.createServer(function(req,res){ res.writeHead(200,{'Content-Type': 'text/plain'}); res.write("Hello"); res.end(); }).listen(8888); Upon starting the server ...

Removing an object from a JSON array based on checkbox selection in Angular 4

0: CategoryId: "31b7a227-9fda-4d14-8e1f-1dee5beeccb4" Code: "GMA0300" Description: "PA-5215: Renamed" Enabled: true Favorite: false Id: "26cfdb68-ef69-4df0-b4dc-5b9c6501b0dd" InstrumentType: null Moniker: "1GMA0300" Name: "Celiac Disease Panel (tTG IgG, tT ...

Launch the file explorer using JavaScript/HTML

Is there a way to launch a real explorer window instead of the browser's directory look? For example, like the windows key + e window... Is there a method using html or JavaScript? I've noticed it in a Firefox add-on called new tab king, but I c ...

Encountering an issue in a Next.js application while building it, where an error is triggered because the property 'protocol' of 'window.location' cannot be destructured due to being undefined

While building my nextjs application, I encountered the following error. My setup uses typescript for building purposes, although I am only using JavaScript. Build error occurred: TypeError: Cannot destructure property 'protocol' of 'window ...

Grab the webpage's URL by collecting the link from the src attribute of the script tag using XSLT

Can XSLT be used to extract a URL link specified within the src attribute of a script tag in an HTML file? Here is an example of the HTML file: <HTML> <BODY> <SCRIPT language="javascript" src="http://myspace.com" type="text/javascript"> ...

The view has no access to $scope but the controller does

I need to display the iso code using a $scope when selecting a country from a list. The list of countries is fetched through a $http call in a factory and then stored in a scope. ///////// get countries //////////////// tableFactory.getCountries().then(f ...

Transform this JavaScript into Vue 3 code

Hey there! I'm currently working on implementing dark mode into my project by following a tutorial. However, the tutorial is based on JavaScript and not Vue, so I'm having some trouble converting this particular section of code to work with Vue 3 ...

Send various pieces of information using Jquery/Ajax

I have encountered a challenge with my script - it currently only sends one value to the requested URL, but I now need it to handle two values. Unfortunately, I haven't been able to figure out how to do this. Each checkbox on the page is paired with ...

Tips on waiting for an event to be processed during a Protractor end-to-end test

I have a straightforward AngularJs 1.4.8 Front-End: https://i.stack.imgur.com/2H3In.png After filling out the form and clicking the OK button, a new person is added to the table. The form resides in the addingPersonController, while the table is control ...

The video player will only start playing after the source has been changed if it was already in play

I am facing an issue with my video player that has thumbnails. The problem is that the video player does not start playing the selected video unless the video is already playing. This means I have to hit the play button first, and then select the thumbnail ...

Unable to transmit form information using HTML/JavaScript/Express Node application

I'm facing a challenge in developing an app that allows me to input event information and then display it on a map. I'm encountering difficulties at the initial stage when it comes to saving the data. Even though Chrome's Inspect tool indica ...

altering the value with the click of a button

I'm new to JavaScript and I've come across a function that adjusts the quantity of ingredients on a recipe. I want to update the value by simply clicking a button. I have jquery included, the classes are properly formatted, and they are linked w ...

Incorporate query strings into every hyperlink within the application

Let me paint you a picture... I've got this lovely Next.js app that's been around for a while, filled with lines of code we've poured our hearts into. Recently, we decided to spice things up by running some ads and now we are itching to see ...

Using the React key attribute for components without distinct identifiers

When dealing with a situation where users need to provide a list of timeframes, it can be tricky to generate a unique key for each component in React. Simply using the index of the array is not sufficient, as items can be removed from the middle of the lis ...

Node.js readline: SyntaxError: Unexpected token =>

Currently, I am diving into node.js and have found myself in need of utilizing the readline module for a new project. Below is the code snippet that I extracted directly from the official readline module example. const readline = require('readline&ap ...