Reputation: 283
I have a svg image with some rect element inside, all identify by ID's. I insert my svg like that :
<object id="svgObject" type="image/svg+xml" data="img/svg/monSvg.svg"></object>
So, for access to rect elements inside I need to use this code :
document.getElementById("svgObject").addEventListener("load",function(){
var svgObject = document.getElementById("svgObject");
var svgDoc = svgObject.contentDocument;
var svgItem = svgDoc.getElementById("monID");
svgItem.style.display ="inline" ;
svgItem.style.fill = "red";
svgItem.style.strokeWidth = "0";
});
So this code works. But I want add a mouse over events on my "svgItem" and a tried with addEventListner, onmouseover etc... But it doesn't work... My event can't access in the Object tag document...
Someone have the solution for this problem ?
Thanks for your help.
Romain.
Upvotes: 2
Views: 5659
Reputation: 4187
To be honest, my first guess was that you can not target individual SVG elements in an <object>
, but I stand corrected. At least in Firefox (Developer Editor), Opera (Developer Editor) and Safari (9.0.2).
Steps to reproduce:
HTML/JS
<script>
function onoff(elm) {
elm.addEventListener('mouseover', function(e) {
elm.style.fill = '#f90';
});
elm.addEventListener('mouseout', function(e) {
elm.style.fill = '';
});
}
window.addEventListener('load', function(e) {
var doc = document.querySelector('#sample'),
svg = doc.contentDocument || doc.getSVGDocument(),
path = svg.querySelectorAll('path'),
i;
for (i = 0; i < path.length; ++i) {
onoff(path[i]);
}
});
</script>
And the SVG I used:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
<g fill="#F00" stroke="#3b5998" stroke-width="4">
<path d="M28,6h44v16l-22,21l-22-21z" fill="#6d84b4"/>
<path d="M28,95h44v-16l-22-21l-22,21z" fill="#6d84b4"/>
<path d="M6,30v42h15l21-21l-21-21z" fill="#afbfde"/>
<path d="M95,30v42h-15l-21-21l21-21z" fill="#afbfde"/>
</g>
</svg>
Now, as I would normally would try to run this from the filesystem directly, it will not work, both files must be served from the same origin which has to be a webserver, otherwise the SVG will load, but you do not get to access it using script.
That is just one of the caveats, and not the thoughest one to deal with.
I personally don't like the idea of accessing the contents of <object>
as document on its own, as it is cumbersome and your mileage may vary based on the browsers you need to support. I'd just embed the <svg>
into the HTML and have the benefits of using pure CSS to deal with hover states.
In which case you'd only had to add a simple rule
path:hover {
fill: '#f90';
}
In your question you have the following line
svgItem.style.display = "inline" ;
SVG elements don't have the concept of display
-flow, although there is some kind of flow going on you usually need to specify exactly where and how you want your elements to be drawn.
Finally, you may want to know why I used both .contentDocument
and .getSVGDocument()
.
Upvotes: 2