0

I have ran into extremely suprising behavior of some older jQuery that does not allow to modify svg element width or height attributes (not styles). It just does not modify them and always silently fails.

It works fine with attributes like mywidth, but not with width.

Note that is related to some very old jQuery version (v1.4.3), but still I am just curious about reasoning behind that.

The setup is simple:

<svg id='mysvg'></svg>

and JS code:

$('#mysvg').attr('width','100');

does nothing, where:

$('#mysvg').attr('mywidth','100');

works fine.

I was supposing some other scripts overrides the changes and tried to affect the attribute after a timeout or on click, but behavior is still the same.

Also I've tried to put breakpoint on attribute modification in Chrome, but it also does not work, it triggers for .attr('mywidht','100') but does not for .attr('width','100). It never generates a console error, always fails silently.

Is there any historical reason or unfamous bug that prevents modifying width and height attribute of svg HTML tag?

Note that with some custom tag like <mysvg> it works also fine and adds width attribute.

JSFiddle reproducing it: https://jsfiddle.net/d8703afx/

Looks like the attr('width') returns some "special" [object SVGAnimatedLength]

Piotr Müller
  • 5,323
  • 5
  • 55
  • 82
  • Can you post an example for us to look at? – Adam H Oct 23 '18 at 21:46
  • Because `svg` is not an image or a standard HTML DOM element, but you can have a look at [here](https://stackoverflow.com/questions/9872947/changing-svg-image-color-with-javascript) to get an idea on how to access or modify the object and inner paths – Towkir Oct 23 '18 at 22:03
  • Sorry don't know the underlying reason, but have had success using plain JS in such situations, eventhough I might use jQuery for the rest of my code. – MSC Oct 23 '18 at 22:06

2 Answers2

0

That $("#mysvg").attr('width') is returning an SVGAnimatedLength object is actually a good hint. The function does not return the attribute, as this DOM method would:

document.querySelector("#mysvg").getAttribute('width')

but the property

document.querySelector("#mysvg").width

which, for SVG elements that implement that property is an object of type SVGAnimatedLength with roughly this structure:

{
    baseVal: {
        unitType: number,
        value: number,
        valueInSpecifiedUnits: number,
        valueAsString: number
    },
    animVal: { /* etc */ }
}

The difference to HTML width properties is that SVG provides for animated values and different unit identifiers.

So probably jQuery, when executing .attr('width', value) tries also not to set the attribute, but the width property to a number, which would be correct for HTML elements. But for SVG it must fail, as the object is readonly.

You can simply set the attribute with the DOM method

document.querySelector("#mysvg").setAttribute('width', 100);
ccprog
  • 20,308
  • 4
  • 27
  • 44
0

The jquery version you are using (1.4.3) was released in 2010, when the up to date IE was still IE8, and we still had to support things like IE6, y'know the word "HTML5" was a bit like "flying car" at this time...

You should not use such an old version of this library nowadays. Many bugs, and new features have been fixed/added in newer versions.

E.g a better support for SVG manipulation, which at this time was still an "upcoming" technology.

So by using an up-to-date jQuery version, (or a slightly newer one) you'll be able to do what you want:

$("#mysvg").attr('xxwidth', '333');
$("#info").append("The xxwidth is: " + $("#mysvg").attr('xxwidth') + '<br>');

$("#mysvg").attr('width', '333');
$("#info").append("The width is: " + $("#mysvg").attr('width'));
<!-- not even up to date... current is 3.3.1 -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<svg id="mysvg"></svg><br>

<span id="info"></span>
Kaiido
  • 123,334
  • 13
  • 219
  • 285