Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

conflicting ids in two different SVG files included in the same HTML document

So I have a single .svg file with a few pre-made gradient effects like this:

<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="1052.4" width="744.09" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" viewBox="0 0 670 680" style="width: 100%; height: 100%;">

<defs>
    <radialGradient id="grad1" cx="50%" cy="50%" r="50%" fx="50%" fy="50%">
        <stop offset="0%" style="stop-color: #a0a0a0;" />
        <stop offset="100%" style="stop-color: #a0a0a0;" />
    </radialGradient>
</defs>
 <g>
  <path id="path1" d="m124 263.35c6.4216-12.385 18.974-0.67157 0.72621z" fill="url(#grad1)">
  </path>
</g>
</svg>

This is a simplified version of my svg file. It represents a map in which each state is a path element. Each state also has a radialgradient tag associated with it. The problem I'm having is that I include this SVG file twice in my HTML document and I alter the radial gradient tags on the svg to alter the color of the state on each map separately.

The maps also have some interactivity in them, I use the following code to load the svg and to add events that bring a state to the front (so its stroke is visible) when the user hovers the mouse over the map:

$divSVG.load("map.svg", function() {
    $svg= $(this).find("svg");
    $svg.find("path").each(function() { 
        $(this).bind("mouseenter", function() {
                var $path= $(this);
            var $parent= $path.parent();
            //its necessary to detach and reattach the element so it comes to the front
            //of the image (there is no z-index in SVG)
            $path.detach();
            $parent.append($path);
            $path
                .css("stroke", "#FF0000")
                .css("stroke-width", "5px");
        });
        $(this).bind("mouseleave", function() {
            $(this)
                .css("stroke", "#FFFFFF")
                .css("stroke-width", "3px");
        });
    }
});

Basically I just remove the element and reattach it to its parent when the element is hovered.

The problem: when the element is reattached on the map that was added first in the document it starts using the radial gradient present on the second map. That means that when I hover the first map the states changes colors to the same colors they have on the second map.

I believe the cause of this is that since its the same file loaded twice the gradient ids are conflicting causing the reattached element to take its color from the last gradient tag found in the HTML document instead of the gradient tag present in its own SVG tag.

So here is my problem, how do I solve it? I don't want to create a new SVG file for each map with unique ids. Nor do I want to manipulate the ids by javascript. Any ideas?

like image 463
Hoffmann Avatar asked Feb 08 '13 13:02

Hoffmann


1 Answers

SVG injectors like Iconic SVGInjector or the newer Iconfu SVGInject handle this issue by making the IDs unique when inserting the SVG into the HTML document. The Iconic injector adds a running number to the ID (grad1 becomes grad1-1), while the Iconfu injector adds a short random string (grad1 becomes something like grad1-4ew8ZeSw).

Making IDs unique is not only necessary if two SVGs use the same ID, but also if the same SVG is used multiple times in an HTML document.

like image 67
Waruyama Avatar answered Sep 28 '22 12:09

Waruyama