Add Onclick Event to Svg Element

Add onclick event to SVG element

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>

Dynamically adding onclick on SVG elements

$(".circle").click(function() {
onclick= "alert('click!')";
})

This should have been

$(".circle").click(function() {
alert('click!');
})
newCircle.setAttribute("onclick","myFunction");

This should have been

newCircle.setAttribute("onclick","myFunction()");

But, these days, the normal way to do this is as follows:

newCircle.addEventListener("click", myFunction);

Add onClick event to a group element (svg) with react

A g element is just an empty container; it can not fire events by itself.

If you run this example, you'll see that you can trigger the click event by clicking on the children of the g element, but you can't if you click in the empty space between them.

You have to use actual shapes to fire events in SVG.

Click handler on svg element

Okay, turns out that the first way of creating a SVG creates the onclick only on the drawn part. That means you can actually do something nice (maybe not useful in your case).

In this fiddle, I created two separate onclicks, one that triggers when you click specifically the drawing (which i made larger so you can see) and one that triggers when you click on the SVG box, by putting a container around it.

HTML :

<div id="svgContainer">
<svg id="firstSVG" class="s" xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="25" fill="red"/>
</svg>
</div>

JS :

document.getElementById('firstSVG').addEventListener('click', function (event) {
document.getElementById("output").innerHTML = "Click works here too !";

}, false);
document.getElementById('svgContainer').addEventListener('click', function (event) {
document.getElementById("output").innerHTML = "Well, a container seems better.";

}, true);

So basically just use a container around the SVG, or just use the click on the drawing

'onclick' does not work on an object-element with an svg-image

After a bit of research, I found that your main issue is:

The <object> tag can not be clicked. (*)

(*)Unless the <object> tag is empty, it's behavior will be the same as an <iframe> tag, which is strictly limited by CORS policy and the browser will block any attempt to modify the source.

Why?

The CORS security policy is a mechanism that uses additional HTTP headers to tell (or give permission) to a browser to use and manipulate the external domain contents.

This is a security policy because imagine this:

Someone has a malicious website called stackoverflow.co. And this malicious person decides to load trough an iframe the website stackoverflow.com and manipulate its content to trick users into a fake login page and when users inputs his private credentials he's not loggin into the official site, so his credentials will be stolen by the malicious site.

Well, CORS is the hero here. Thanks to this security policy, the remote servers can send an additional header that is seen like this: Access-Control-Allow-Origin: * and the browser determines that if any of this contents are loaded trough an <iframe> or <object> tag, any attempt to modify the contents of this should be blocked.

Since in 2019 this is now a standard in the web, most browsers detect this CORS header and prevents this kind of exploit.

So, what should you do?

Well, if your issue is that you need to load the svg, the quickest solution is to load it trough an <img> tag.

Otherwise, there is no way you'll be able to inject, use, handle or whatever in an <object> nor <iframe> tag with the CORS header included. Except for the onload.

Aditional sources:

The user who answered a similar question time ago can be found here.

Add click event on elements of an embedded SVG in javascript

Okay using your comments I found an answer to my problem. I added this code in the svg itself.

<script type="text/javascript"> <![CDATA[
function addClickEvents() {
var countries = document.getElementById('svg1926').childNodes;
var i;
for (i=0;i<countries.length;i++){
countries[i].addEventListener('click', showCountry);
}
}

function showCountry(e) {
var node = e.target;
if (node.id != 'ocean') {
node = getCorrectNode(node);
}
alert(node.id);
}

function getCorrectNode(node) {
if (node.id.length == 2 || node.id == 'lakes') {
return node;
}
return getCorrectNode(node.parentNode);
}
]]> </script>

The function addClickEvents is triggered when the svg loads.
But I still have another problem with this. I have to embed this svg (with the code) into a HTML document using

<embed src="circle1.svg" type="image/svg+xml" />

Instead of alerting the id, I have to place it into a div in the HTML document.
How do I get this id from the svg?

How to add a click event inside a shape in a SVG?

Replace none filling with the transparent one.

const svg = document.querySelector('#svg');const svgNS = svg.namespaceURI;const rect = document.createElementNS(svgNS, 'rect');
const clickedOnRect = () => { alert('Rectangle was clicked');}
rect.setAttributeNS(null, 'x', '100');rect.setAttributeNS(null, 'y', '100');rect.setAttributeNS(null, 'width', '100');rect.setAttributeNS(null, 'height', '100');rect.setAttributeNS(null, 'fill', "transparent");rect.setAttributeNS(null, 'stroke', "red");rect.setAttributeNS(null, 'stroke-width', '5');rect.setAttributeNS(null, 'tab-index', '1');rect.setAttributeNS(null, 'cursor', 'pointer');rect.addEventListener('click', ($event) => { clickedOnRect();});
svg.appendChild(rect);
svg {  border: 1px solid #000000;}
<svg id='svg' width="400" height="400"></svg>


Related Topics



Leave a reply



Submit