Create clickable svg image object using onclick avoiding absolute positioning

I tried changing the images on my site from img to svg , changing the img tags to embed and object tags. But the implementation of the onclick function, which was previously contained in the img tag, turned out to be the most complex.

I found that onclick has no effect when placed inside an object or embed tag.

So, I created a div exclusively for svg and put onclick in this div tag. But without effect, if the visitor does not click on the edges / padding of the image.

I read about overlaying a div , but try to avoid using absolute positioning, or to specify position altogether.

Is there any other way to apply onclick to svg?

Has anyone encountered this issue? Questions and suggestions are welcome.

+45
html css svg
Feb 19 '10 at 12:05
source share
10 answers

You may have an onclick event in svg itself, I do this all the time in my work. make a rectangle over the space of your svg (so define it last, remember that svg uses the painters model)

 rect.btn { stroke:#fff; fill:#fff; fill-opacity:0; stroke-opacity:0; } 

then add onclick as the rect attribute (this can be done using js or jquery).

 <div> <svg xmlns="http://www.w3.org/2000/svg" version="1.1"> <g> <circle ... //your img svg <rect class="btn" x="0" y="0" width="10" height="10" onclick="alert('click!')" /> </g> </svg> </div> 

this will work in most modern browsers, http://caniuse.com/svg ... although if you need cross-compatibility, you can implement Google Chrome Frame. http://www.google.com/chromeframe

+54
Apr 18 2018-12-18T00:
source share

It started with a comment on the RGB solution, but I could not fit it, so I converted it to a response. The source of inspiration for which are exclusively RGB.

The RGB solution worked for me. However, I would like to point out a couple of points that may help others coming to this post (like me) who are not so familiar with which SVG, and who could very well generate their SVG file from a graphics package (like me did it).

Therefore, to apply RGB solutions, I used:

CSS

  <style> rect.btn { stroke:#fff; fill:#fff; fill-opacity:0; stroke-opacity:0; } </style> 

Jquery script

 <script type="text/javascript" src="../_public/_jquery/jquery-1.7.1.js"></script> <script type="text/javascript"> $("document").ready(function(){ $(".btn").bind("click", function(event){alert("clicked svg")}); }); </script> 

HTML code to encode the inclusion of your pre-existing SVG file in the group tag inside the SVG code.

 <div> <svg xmlns="http://www.w3.org/2000/svg" version="1.1"> <g> <image x="0" y="0" width="10" height="10" xlink:href="../_public/_icons/booked.svg" width="10px"/> <rect class="btn" x="0" y="0" width="10" height="10"/> </g> </svg> </div> 

However, in my case, I have several SVG icons that I want to click on, and including each of them in the SVG tag has become cumbersome.

Therefore, as an alternative approach where I could use classes, I used jquery.svg. This is probably a shameful application of this plugin that can do all kinds of things with SVG. But it worked using the following code:

 <script type="text/javascript" src="../_public/_jquery/jquery-1.7.1.js"></script> <script type="text/javascript" src="jquery.svg.min.js"></script> <script type="text/javascript"> $("document").ready(function(){ $(".svgload").bind("click", function(event){alert("clicked svg")}); for (var i=0; i < 99; i++) { $(".svgload:eq(" + i + ")").svg({ onLoad: function(){ var svg = $(".svgload:eq(" + i + ")").svg('get'); svg.load("../_public/_icons/booked.svg", {addTo: true, changeSize: false}); }, settings: {}} ); } }); </script> 

where is the HTML

 <div class="svgload" style="width: 10px; height: 10px;"></div> 

The advantage of my thinking is that I can use the appropriate class where icons are ever needed and avoid a lot of code in the HTML body, which contributes to readability. And I only need to include the previously existing SVG file once.

Editing: Here is a more accurate version of the script provided by Keith Wood: using the .svg download URL setting.

 <script type="text/javascript" src="../_public/_jquery/jquery-1.7.1.js"></script> <script type="text/javascript" src="jquery.svg.min.js"></script> <script type="text/javascript"> $("document").ready(function(){ $('.svgload').on('click', function() { alert('clicked svg new'); }).svg({loadURL: '../_public/_icons/booked.svg'}); }); </script> 
+6
Oct 24 '12 at 18:08
source share

I have been working on the latest versions of Firefox, Chrome, Safari and Opera.

It relies on a transparent div in front of the object, which has an absolute position and sets the width and height to close the object tag below.

Here it is, I'm a little lazy and used the built-in styles:

 <div id="toolbar" style="width: 600px; height: 100px; position: absolute; z-index: 1;"></div> <object data="interface.svg" width="600" height="100" type="image/svg+xml"> </object> 

I used the following JavaScript to connect events to it:

 <script type="text/javascript"> var toolbar = document.getElementById("toolbar"); toolbar.onclick = function (e) { alert("Hello"); }; </script> 
+4
Aug 18 '10 at 21:57
source share

It worked by simply replacing the <embed/> with <img/> and removing the type attribute.

For example, in my code instead

 <embed src=\"./images/info_09c.svg\" type=\"image/svg+xml\" width=\"45\" onClick='afiseaza_indicatie($i, \"$indicatii[$i]\")'> 

which does not respond to a click, I wrote:

 <img src=\"./images/info_09c.svg\" height=\"25\" width=\"25\" onClick='afiseaza_indicatie($i, \"$indicatii[$i]\")'> 

It works in Internet Explorer and Google Chrome, and I hope in other browsers too.

+3
Mar 24 '13 at 0:00
source share

You can use the following code:

 <style> .svgwrapper { position: relative; } .svgwrapper { position: absolute; z-index: -1; } </style> <div class="svgwrapper" onClick="function();"> <object src="blah" /> </div> 

b3ng0 wrote similar code, but it does not work. The z-index of the parent must be auto.

+1
Sep 15
source share

Have you explored the use of the z-index CSS property to make a container container "on top" of svg? Since the div is (presumably) transparent, you will still see the image exactly the same as before.

I believe this is the best practical, non-hack designed to solve your problem. z-index is only useful for elements that have the position fixed , relative property, or, as you have heard, absolute . However, you really do not need to move the object.

For example:

 <style> .svgwrapper { position: relative; z-index: 1; } </style> <div class="svgwrapper" onClick="function();"> <object src="blah" /> </div> 

For what it's worth, it would also be a little more elegant and safe not to use onClick at all, but instead to bind the click event with javascript. But this is another problem.

0
Feb 19 '10 at 20:23
source share

Assuming you don't need cross-browser support (which is not possible without the IE plugin), have you tried using svg as your background image ?

Experimental material for sure, but I thought that I would say this.

0
Mar 24 '10 at 15:09
source share

Perhaps you are looking for the property of the SVG element pointer-events, which you can read about in the docs of the SVG w3C workgroup .

You can use CSS to set what happens to the SVG element when clicked, etc.

0
Apr 01 '13 at 2:08
source share

When embedding SVG with the same source using <object> , you can access the internal content using objectElement.contentDocument.rootElement . From there, you can easily attach event handlers (e.g. via onclick , addEventListener() , etc.)

For example:

 var object = /* get DOM node for <object> */; var svg = object.contentDocument.rootElement; svg.addEventListener('click', function() { console.log('hooray!'); }); 

Note that this is not possible for cross-origin <object> elements unless you also control the origin server <object> and can set CORS headers there. For cross-origin cases without CORS headers, access to the contentDocument blocked.

0
Apr 13 '16 at 18:43
source share

If you just use inline svg, no problem.

 <svg id="svg1" xmlns="http://www.w3.org/2000/svg" style="width: 3.5in; height: 1in"> <circle id="circle1" r="30" cx="34" cy="34" onclick="circle1.style.fill='yellow';" style="fill: red; stroke: blue; stroke-width: 2"/> </svg> 
0
Dec 08 '17 at 16:48
source share



All Articles