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 onclick
s, 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
Failed to Load Resource: the Server Responded With a Status of 404 (Not Found) CSS
How to Change the Time Format (12/24 Hours) of an <Input>
How to Manually Trigger Click Event in Reactjs
How to Get Angular to Reload the Same Page But With a Different Argument
Multiple Select Dropdown Not Working With Ng-Option
How to Embed Pdf File With Responsive Width
What to Do Regular Expression Pattern Doesn't Match Anywhere in String
Applying an Ellipsis to Multiline Text
When Submitting a Get Form, the Query String Is Removed from the Action Url
How to Make an Image Center (Vertically & Horizontally) Inside a Bigger Div
In Angular 4, How to Dynamically Set Min Date and Max Date in Date Picker
Css Absolute Position With X Scrolling
How to Position Elements Next to Each Other in a Div
How to Give Multiple Conditions in *Ngif Statement in Angular 6
Rendering HTML Content With @Html.Raw in Razor Mail Template
How to Prevent a User from Entering Negative Values in HTML Input