chris Frisina
chris Frisina

Reputation: 19688

Click handler for Button with SVG

I have a button with an SVG as its logo:

<div id="measure-representation">
  <button type="button" class="btn" data-state="audio">Audio
    <svg xmlns="http://www.w3.org/2000/svg" version="1.1" class="svg" height="80px" data-state="audio">
      <circle cx="50" cy="50" r="20" stroke="black" stroke-width="1" fill="#80ff00" opacity="1"></circle>
    </svg>
  </button>
</div>

The button has data-state="audio", and because I am troubleshooting, the SVG does as well (not sure if SVG supports data-state). I am trying to allow the user to click the button and then get the data-state from it, and do other things using that info. The problem is if I click directly on the SVG within the button, it thinks I am clicking on the SVG, and not the button. ( i have verified this by forcing the height and width attrivutes of the SVG, and clicking on the surrounding portion of the button. I get the data-state when I click the button, but I get nothing when I click the SVG.

I think this might be the selector code I am using (in backbone), but I alos think it might be solved with how I structure the HTMl of the button and the SVG, not sure which way is better convention, or possible.

Backbone view and click handler:

el : $("#measure-representation"), // Specifies the DOM element which this view handles

events : {
  "click .btn" : "cycle",  //Trying to differentiate and/or 
  "click .svg" : "cycle"   //capture the btn click or the SVG click
},
....
cycle: function(button) {
  //This works if I click the button
  var buttonNewState = $(button.target).data('state');
  //Tried different ways to select the SVG from the JQuery event 
  var svgNewState = ....
},

The paramater button in the cycle function is a JQuery event Object, so $(button.target)[0] is returning the HTML of what I am clicking on. It returns the HTML of the button (which includes the SVG and the paths), or it is the SVG (and includes the paths), or it is the path I click on. Would I have to put the data-state on every element in the button? or what better selector should I use to bubble up to get the data-state of the button?

The SVG's are more than just a circle, so font-awesome cant be substituted.

Upvotes: 1

Views: 1714

Answers (2)

Nick Tomlin
Nick Tomlin

Reputation: 29271

If you only want the data attribute from the button, bind the event to the button and use e.currentTarget:

events : {
  "click .btn" : "cycle",  //Trying to differentiate and/or   
},
....
cycle: function(e) {
  //This works if I click the button
  var buttonNewState = $(e.currentTarget).data('state');

},

This allows the event to bubble up to the element that you've bound it to which can be accessed via e.currentTarget. e.target will still refer to the exact element that was clicked.

Upvotes: 1

YD1m
YD1m

Reputation: 5905

Try this way

events : {
  "click .btn" : "cycle",  //Trying to differentiate and/or 
  "click .svg" : "cycle"   //capture the btn click or the SVG click
},
....
cycle: function(e) {
  //This works if I click the button
  var audio;
  if($(e.target).is('button'))
    audio = $(e.targe).data('state');
  else
    audio = $(e.targe).closest('button').data('state');     
},

Upvotes: 0

Related Questions