What could be the reason why my contentDocument object is returning null?

My objective is to change the viewBox attribute in an SVG file retrieved from an API server through a websocket by scrolling the mouse wheel. Here's how I accomplish this:

  1. Create

    <object id={"std-chart"}
    class="mouse-wheel-pannable"
    type="image/svg+xml"
    />
    

  2. Receive data svgStr from the websocket, then dynamically insert it into the <object> element.

    
    let obj = document.getElementById('std-chart');
    var objUrl = 'data:image/svg+xml;utf8,'+ svgStr;
    obj.setAttributeNS(null,'data',objUrl);
    

where svgStr looks something like this:

<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="1081" height="184" viewBox="0 0 1081 184"  > 
<path d="M 0.0 98.7 L 0.3 98.7 .../> 
</svg>

Q1. Why do I have to append data:image/svg+xml;utf8, before the svgStr? Without it, the image doesn't display correctly.

  1. In my mouseWheelScroll() function, I attempt to locate the svg element and update its viewBox. However, I encounter the issue that contentDocument returns null.

    
    var svgObjs = document.getElementsByClassName("mouse-wheel-pannable");
    var svgObj = svgObjs[0].contentDocument;                    //svgObj returns null 
    var svg = svgObj.getElementsByTagName('svg')[0];            //error here
    svg.setAttributeNS(null, 'viewBox', someNewViewBox);
    

    How can I obtain a valid contentDocument i.e. <svg> element to modify the viewBox?

Thank you.

I experimented using <embed> instead of <object>, saw the embed item in the Chrome console, yet I still struggle with accessing the underlying <svg>. Is the <svg> shown in the image below still relevant? Please click here to view the chrome console screenshot.

Thank you.

Further testing revealed that setting <object data=xxxxxx.svg/> initially, i.e., storing the svg content in a file and loading it when initializing <object>, works perfectly. The question arises of how to dynamically "reload" the svg content for the <object>.

Thank you.

Answer №1

Q1. I'm a bit unsure why it's necessary to include data:image/svg+xml;utf8

The data attribute of an <object> needs to be a URL. The string <svg>...</svg> is not considered a URL.

By adding data:image/svg+xml;utf8, in front of it, you create a Data URL. The image/svg+xml indicates that the URL is for an SVG image. The utf8 specifies how the text is encoded.

It's important to note that Data URLs follow the same rules as other URLs. As SVGs may contain characters that are not allowed in URLs, it's recommended to URL encode the SVG before creating the Data URL.

var objUrl = 'data:image/svg+xml;utf8,'+ encodeURI( svgStr );

Question: How can I access a valid contentDocument for manipulation, such as changing the viewBox?

Unfortunately, this isn't possible with a Data URL. Data URLs are treated as if they belong to a different domain, making it impossible to access the contentDocument of cross-domain objects.

https://html.spec.whatwg.org/#origin:document-4

"If the Document was generated from a data: URL A unique opaque origin assigned when the Document is created."

So, how can I dynamically make the <object> reload the svg content?

Have you considered inserting your SVG directly into the page instead of using an <object>? It might simplify the process and avoid potential limitations.

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 modify the text color of table TD using Javascript?

I have experience with HTML/CSS, for example I can make text turn red using the code <table><tr><td style="color:#f00;">text</td>. However, I am struggling with JavaScript. When I try to change the color of a table cell u ...

Changing the default route in Angular 2 based on conditions

I'm currently developing an application where, upon entering the page, the default route for the user is the "Login" page. However, I want to implement a condition based on whether the user has a local storage variable (id) set. If this variable exist ...

Submitting requests in Node.js Express

Can a request for a specific route be dropped using Node.js and express? For example, not returning an HTTP status or any headers, but simply closing the connection? app.get('/drop', function(req, res) { //What is the method to drop the requ ...

Issue: Connection Problem in React, Express, Axios

I've encountered an issue while attempting to host a website on an AWS EC2 instance using React, Express, and Axios. The specific problem I'm facing is the inability to make axios calls to the Express back-end that is running on the same instanc ...

The error code "invalid_code" occurred when attempting to send a request to the oauth.access URL via Slack

Recently, I've been facing an issue while trying to authenticate my app with Slack. Everything was running smoothly for a few days until it started showing me an error message invalid_code const requestBody = qs.stringify({ code: code, redir ...

Angular binding for selecting all data

Upon checking a checkbox for a single item, the bound data is retrieved and added to an array. However, this does not happen when using selectAll. Code snippet in Angular for obtaining the object of a checked item: $scope.selectedOrganisations = []; $sco ...

Enhancing Sound with Angular 2 - A Guide to Implementing

Trying to incorporate an audio element linked to a toast notification using toastr.js. However, encountering an issue with the audio continuously looping even after the toast notification is hidden. toastr.warning(eventData.type); self.eventAudio[eventDat ...

Learn how to pass an id from the query parameters to the getInitialProps function in Next.js

Looking to create a basic website that displays content from a database? Utilizing the getInitialProps function from Next.js documentation can help with server-side rendering: https://nextjs.org/docs/api-reference/data-fetching/getInitialProps#getinitialpr ...

Using Ember JS to loop over a JSON array of objects and dynamically generate elements

Looking to dynamically generate a dropdown menu with options sourced from a JSON array of objects. Here is an example of the JSON array: var curr_sel = [ {v:"1", n:"USD"}, {v:"2", n:"GBP"}, {v:"3", n:"CAD"}, {v:"4", n:"AUD"}, {v:"5", n ...

Transform the header style columns of react-js Material-tables into rows

Currently experimenting with gradient designs on a material table. While I am able to apply the right color combination to the rows, I seem to be getting column-based results on the title of the table. Attached is a screenshot of my output for reference. ...

continuously adjust the cost

I'm struggling with incorporating a JavaScript function that is required for my school project. The task at hand is to create a store where the price updates dynamically when quantities are added or removed. The +/- buttons are functioning correctly; ...

What is the best way to choose the next adjacent element using a CSS selector with Python Selenium?

The structure of the DOM is as shown below: <ul> <li> <a href="#" role="button" class="js-pagination link" data-page="1">1</a> </li> <li> <a href="#" role="button" class="js-pagination link active" data ...

Exploring AngularJS and its ng-repeat directive along with ng-style

I'm having trouble getting ng-style to work properly with ng-repeat. Here is my code snippet: <div style="display:table-row" ng-repeat="row in Data.Communications" id="{{row.Guid}}"> <div style="display:table-cell;"> <img ng ...

Is there a way to generate a button that displays the subsequent 5 outcomes from the database without navigating away from the current

I am looking to implement a button on my webpage that, once clicked, will load the next set of five questions from my database. I prefer not to use pagination or the GET method to prevent users from navigating back to previously answered questions. My goa ...

What is the best way to specify the stream responseType for my client?

Is there a way to download a file from my express js app using AJAX instead of server-side handling? const response = await Axios({ method: 'GET', url: url, responseType: 'stream' }) Instead of piping the data directly to ...

The three-dimensional object created using Three.js depicts a split torus design with a striking

I have a unique goal of splitting shapes such as a torus, circle, triangle, etc., using a custom plane. Once the shape is split into two parts, each part should be draggable separately. Currently, I am able to split the torus, but I'm facing some iss ...

Developing a perpetually scrolling container within a webpage

I am attempting to implement a scrollable div on my webpage that can continuously load content. I am currently using the following code snippet for this --> http://jsfiddle.net/cyrus2013/Qq85d/ $(document).ready(function(){ function loadMoreContent() ...

Make changes to external CSS using HTML and JavaScript

Is it possible to dynamically change the value of a background in an external CSS file using JavaScript? Currently, all my pages are connected to a CSS file that controls the background for each page. I am attempting to modify the background by clicking a ...

Tips for translating an HTML webpage from Arabic to English

I have a bootstrap site with HTML pages but no backend functionality. How can I manually translate from Arabic to English, given that I already have the translations for all content and don't need to rely on translation tools? Is there a way to map Ar ...

What is the best way to determine when all asynchronous tasks and callbacks have been completed so that we can proceed securely?

Here is a code snippet that reads a file containing documents sorted by categories and values in descending order. It then modifies the documents with the highest value for each category. Below is the code: var MongoClient = require('mongodb'). ...