biggdman
biggdman

Reputation: 2096

Add onclick event to SVG element

I found this example in a SVG tutorial that explains how you can use an onclick event handler for a SVG element. It looks like the code below:

<svg xmlns='http://www.w3.org/2000/svg' version='1.1' height='600' width='820'>

  <script type="text/ecmascript"><![CDATA[
      function changerect(evt)
      {
        var svgobj=evt.target;
        svgstyle = svgobj.getStyle();
        svgstyle.setProperty ('opacity', 0.3);
        svgobj.setAttribute ('x', 300);
      }
    ]]>
  </script>

  <rect onclick='changerect(evt)' style='fill:blue;opacity:1' x='10' y='30' width='100'
        height='100' />
</svg>

However, this doesn't seem to work. Nothing happens when I click on the element.

Perhaps it is important to mention the fact that I am displaying the SVG from inside a PHP script, using echo. Also, note that the content generated by the PHP script is brought into the page using AJAX and XMLHttpRequest().

Could this perhaps have anything to do with it? Thanks a lot for any help.

Upvotes: 26

Views: 120430

Answers (9)

Rooster242
Rooster242

Reputation: 920

Move the onlClick handler out of the svg and add the event to the svg itself. You may intermittently get the rect in the event handler instead of the svg in which case you can do this:

if (event.target.tagName !== 'svg') {
  event.target = event.target.closest('svg');
}

So to refactor your code:

<script type="text/ecmascript"><![CDATA[
    function changerect(evt) {
      if (evt.target.tagName !== 'svg') {
        evt.target = event.target.closest('svg');
      }
      var svgobj = evt.target;
      svgstyle = svgobj.getStyle();
      svgstyle.setProperty ('opacity', 0.3);
      svgobj.setAttribute ('x', 300);
    }
  ]]>
</script>

<svg onclick='changerect(evt)' xmlns='http://www.w3.org/2000/svg' version='1.1' height='600' width='820'>
  <rect style='fill:blue;opacity:1' x='10' y='30' width='100' height='100' />
</svg>

Upvotes: 0

Cyrille
Cyrille

Reputation: 3597

Add an event listener to the svg node:

svgobj.addEventListener("click", myFunction);

Upvotes: 1

sweety santhosh k
sweety santhosh k

Reputation: 1

we can simply add an onclick event to svg

  1. <img class="video-svg" id="play" onclick="playVid(id)" src="assets/img/logo/play svg.png">

then we can give css which will make the effect, for that we need to give position as absolute and z-index to 200 which will make the click event for svg

2.

.video-svg {
   margin: auto;
   top: 0;
   bottom: 0;
   left: 0;
   right: 0;
   height: 7%;
   background: no-repeat;
   border: none;
   z-index: 200 !important;
   width: 10% !important;
   position: absolute !important;
}

Upvotes: -1

jlewis90
jlewis90

Reputation: 51

I had the same problem, and the answer regarding the z-index placing it on top of the div helped!

However, I found that you do not need to wrap the svg in a div, you can just z-index it to the top instead as long as the parent is positioned.

Upvotes: 0

Godly Mathew
Godly Mathew

Reputation: 109

Demo in JSFiddle

    var _reg = 100;
    var _l = 10;

    // Create PATH element
    for (var x = 1; x < 20; x++) {
        var pathEl = document.createElementNS("http://www.w3.org/2000/svg", "path");
        pathEl.setAttribute('d', 'M' + _l + ' 100 Q 100  300 ' + _l + ' 500');
        pathEl.style.stroke = 'rgb(' + (_reg) + ',0,0)';
        pathEl.style.strokeWidth = '5';
        pathEl.style.fill = 'none';
        $(pathEl).mousemove(function(evt) {
            $(this).css({ "strokeWidth": "3", "stroke": "#ff7200" })
                .hide(100).show(500).css({ "stroke": "#51c000" })
        });

        $('#mySvg').append(pathEl);
        _l += 50;
    }

Upvotes: 4

miah
miah

Reputation: 10433

It appears that all of the JavaScript must be included inside of the SVG for it to run. I was unable to reference any external function, or libraries. This meant that your code was breaking at svgstyle = svgobj.getStyle();

This will do what you are attempting.

<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns='http://www.w3.org/2000/svg' version='1.1' height='600' width='820'>

  <script type="text/ecmascript"><![CDATA[
      function changerect(evt) {
        var svgobj=evt.target;
        svgobj.style.opacity= 0.3;
        svgobj.setAttribute ('x', 300);
      }
    ]]>
  </script>

  <rect onclick='changerect(evt)' style='fill:blue;opacity:1' x='10' y='30' width='100'height='100' />
</svg>

Upvotes: 31

eQ19
eQ19

Reputation: 10701

I would suggest this method of onclick event handler for a svg element:

var svgobj = parent_svg.find('svg')[0].children;

for (i = 0; i < svgobj.length; i++) {
   element = svgobj[i];
   element.style = "cursor: pointer;";
   $(element).click(function(evt){console.log($(this))});
}  

Cek first whether your svgobjis passed to console.log when it is getting an onclick event handler. From that point you can pass to whatever functions to handle the element.

You may see on how it is working at a sample here:

https://jsfiddle.net/chetabahana/f7ejxhnk/20/

Note on how to use this sample:
- Change the status on the SVG Diagram to Printed option,
- Click one of the element then cek the output in your console.

Upvotes: 0

Michael Mammoliti
Michael Mammoliti

Reputation: 1597

If you don't need to click specific parts of the svg this might be a possible solution:

Put a div on top and add events to that div. z-index is not needed if the svg element is before the div tag in the html structure.

HTML

<div class='parent'>
  <div class='parent-events'></div>
  <div class='my-svg'><svg></svg></div>
</div>

CSS

.parent {
  position: relative;
}

.my-svg {
  position: relative;
  z-index: 0;
}

.parent-events {
  position: absolute;
  width: 100%;
  height: 100%;
  z-index: 1
}

Javascript

const eventArea = document.querySelector('.parent-events');
eventArea.addEventListeners('click', () => {
  console.log('clicked');
});

Upvotes: 2

user3204205
user3204205

Reputation: 1

Make sure to add className/id to <use>; or to use the actual SVG path/element also, if you're detecting outside of SVG script scope:

<svg rel='-1' class='**ux-year-prev**' width="15px" height="15px" style="border:0px solid"><use class='**ux-year-prev**' xlink:href="#svg-arrow-left"></use></svg>

Upvotes: -1

Related Questions