Making an svg image object clickable with onclick, avoiding absolute positioning

I have tried to change the images on my site from img to svg, changing img tags to embed and object tags. But, implementing the onclick function, which previously was contained in the img tag, is proving most difficult.

I found onclick had no effect when placed inside the object or embed tag.

So, I made a div exclusively for the svg, and placed onclick in this div tag. But, no effect unless visitor clicks on the edges/padding of the image.

I have read about overlaying a div, but am trying to avoid using absolute positioning, or specifying position at all.

Is there another way to apply onclick to a svg?

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


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

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

then as an attribute to the rect add the onclick (this can be done with js or jquery as well).

<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 almost all browsers: http://caniuse.com/svg


If you just use inline svg there is 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>
  

This started as a comment on RGB's solution but I could not fit it in so have converted it to an answer. The inspiration for which is entirely RGB's.

RGB's solution worked for me. However, I wished to note a couple of points which may help others arriving at this post (like me) who are not that familiar which SVG and who may very well have generated their SVG file from a graphics package (as I had).

So to apply RGB's solutions I used:

The CSS

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

The 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>

The HTML to code 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 which I wish to be clickable and incorporating each of these into the SVG tag was starting to become cumbersome.

So as an alternative approach where I could employ Classes I used jquery.svg. This is probably a shameful application of this plugin which can do all sorts of stuff with SVG's. 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 HTML

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

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

Edit: Here is a neater version of the script courtesy of Keith Wood: using .svg's load 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>