5

I have the following markup (HTML with native SVG):

<!doctype html>
   <!-- ...    
        html-Elements 
        ... --> 
   <svg version="1.1" ... >
        <defs> <circle id="infop" cx="0" cy="0" r="9" /> </defs>
        <!-- ... 
             svg Elements
             ... --> 
        <svg> <!-- to have separate coordinate-system -->
            <g id="outSvg"></g>
        </svg>
    ...

A js-method outputs a line and several <use href="infotop"> Elements to #outSvg (to become a graph). The <use> Elements have onmouseover-Events to show tooltips.

Now, when it comes to retrieving the coordinates in the onmouseover-function of the <use> i run into problems:

I tried the following different approaches to retrieve the values:

function showInfo(evt){

    console.log("target: "+evt.target);
    console.log("AttrNS: "+evt.target.getAttributeNS(null,"x"));
    console.log("Attrib: "+evt.target.getAttribute("x"));
    console.log("basVal: "+evt.target.x.baseVal.value);
    console.log("corrEl: "+evt.target.correspondingUseElement.x.baseVal.value);

producing the following output:

    //target -> ** [object SVGUseElement] in FF, in all other browsers: [object SVGElementInstance])
    //AttrNS -> Works only in FF
       // * Uncaught TypeError: Object #<SVGElementInstance> has no method 'getAttributeNS'
    //Attrib -> Works only in FF
       // * Uncaught TypeError: Object #<SVGElementInstance> has no method 'getAttribute'
    //basVal -> works only in FF
       // * Uncaught TypeError: Cannot read property 'baseVal' of undefined
    //corrEl -> fails in FF but works in Ch, O and IE

Browsers:FF10, Ch16, O11.61, IE9

Question:

Why is getAttribute() failing in the other browsers? Am I missing something important? Is there a consistent way to retrieve the values crossbrowser? (Besides via a switch between evt.target.x and evt.target.correspondingUseElement.x)

important: vanilla js only, and I know about browserswitches, thats not the point! I'll provide a fiddle if needed, as soon as i find the time. Finally - thank you for reading this!

EDIT: * added the js-errors

EDIT2: ** FF returns another Object than the other browsers

Christoph
  • 50,121
  • 21
  • 99
  • 128
  • Seems you already found a way. Use either `target.x` or `target.correspondingUseElement.x`. Should not be difficult to create a wrapper function for SVG attribute access. – Felix Kling Feb 14 '12 at 11:06
  • Well, I find your solution rather unsatisfying... – Christoph Feb 14 '12 at 11:26
  • @Christoph, people spend their own time to try to help you FOR FREE. Shouldn't you be grateful? – Allen Zhang Nov 25 '14 at 00:53
  • @Allen I explicitely asked if there is a way that works crossbrowser without using a wrapper function - am I not allowed to express my feelings about an unsatisfactory answer then (which suggests a solution I already figured out by myself anyway)? Erik for example provided some very useful information, that's why I upvoted his answer and explicitely thanked him. – Christoph Nov 25 '14 at 21:28

4 Answers4

8

Well, after reading Erik Dahlströms answer, i noticed that FF behaves wrong. It should return an Element-Instance instead of the Use-Element directly.

I use the following code now:

var el = (evt.target.correspondingUseElement)?evt.target.correspondingUseElement:evt.target;

console.log(el.getAttribute("x"));

This way i can retrieve the Attributes via getAttribute() consistently in all browsers.

Christoph
  • 50,121
  • 21
  • 99
  • 128
  • I think for cross browser solution it is better not to use elements if you want to have access via JS. You can always replace them in JS with normal elements. – Bharata Jan 13 '19 at 11:34
  • @Bharata what exactly is causing cross browser issues in your opinion? I haven't touched SVG in a while, so I'm not sure which problem you are referring to, but I'm happy to include it in the answer - the question is six years old after all;-) – Christoph Jan 14 '19 at 16:14
  • Because for example in IE10 I had the problem with getting from attributes of elements. And with `evt.target.correspondingUseElement` I did not solve this problem. I have replaced all elements with elements and the problem was gone. I have nothing against your answer. I wrote my comment only as a hint. – Bharata Jan 14 '19 at 17:47
  • @Bharata Thank you for your comment! This is exactly how the SO community should work! If I have time, I will look what exactly happened there (`` support being dropped in IE10? As you can see from my question it "use"d (hehe) to work in IE9). On the other hand, IE does not have too much relevance anymore anyway... – Christoph Jan 17 '19 at 14:08
2

can you try this? evt.target.getAttributeNode("x").nodeValue . I tried this in safari,chrome,Firefox its working fine.

Rajkamal Subramanian
  • 6,884
  • 4
  • 52
  • 69
2

As far as I know Firefox doesn't support SVGElementInstance.

Here are a couple of tests for SVGElementInstance from the w3c SVG 1.1 Second Edition testsuite to verify:

What you should do is to provide a fallback solution if the SVGElementInstance isn't there, which is easy enough to detect, e.g:

if (elm.correspondingUseElement) {
  /* elm is a used instance, not a real element */
} else {
  /* fallback solution */
}

If the element is an SVGElementInstance it will have the correspondingUseElement property, otherwise it won't have it. Normal svg elements will not have this property, only used instances will have it.

Erik Dahlström
  • 59,452
  • 12
  • 120
  • 139
0

Did you try evt.target.getAttributeNS(evt.target.parent.namespaceURI,"x") ?

mihai
  • 37,072
  • 9
  • 60
  • 86
  • `evt.target.getAttributeNS(null,"x");` does the same and doesn't change the fact, that the svgElement seems to lack the according method in the other browsers. – Christoph Feb 14 '12 at 12:06