So I have an SVG imported via the <object>
tag and it has a onclick="functionName();
attached to it, but it doesn't appear to work. So I tried adding the following script in the SVG:
<svg tag here etc
<defs>
<script type="text/javascript">
<![CDATA[
document.addEventListener('click', test());
]]>
</script>
<linearGradient id="bbc50e5b-4734-4535-94bd-b30475bdd571" data-name="Testingspace" x1="15" y1="310" x2="320" y2="5" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#ccc"/>
<stop offset="1" stop-color="#fff"/>
</linearGradient>
</defs>
the rest of SVG here
My HTML:
<object id="sidebartoggle" data="graphics/test.svg" type="image/svg xml" onclick="toggleSidebar();" style="top:50%;right:1%;position:fixed;display:flex;justify-content:flex-end;width:500px;transform: translateX(99%); z-index:9999999;" >
</object>
...but it simply doesn't work. What's the required workaround here? What should I do to accomplish my goal - bind a click event on the SVG, which executes a function from the JS file.
CodePudding user response:
The onclick event won't be bound to your object, since you're actually clicking/targeting the object's inner content (svg DOM).
As a workaround you could apply a css pointer-events:none
to your object element and bind your click event to an auxiliary wrapping element.
function toggleSidebar(){
console.log('clicked');
}
.svg-wrp{
cursor:pointer;
}
.svgObject{
display:inline-block;
font-size:36px;
width:1em;
height:1em;
background-color:transparent;
border:1px solid red;
}
<h3>css: "pointer-events:none" – click enabled</h3>
<div class="svg-wrp" onclick="toggleSidebar()" >
<object class="svgObject" id="sidebartoggle01" data="data:image/svg xml," type="image/svg xml" style="pointer-events:none" ></object>
</div>
<h3>Original <object> – click event is not available</h3>
<div class="svg-wrp" onclick="toggleSidebar()" >
<object class="svgObject" id="sidebartoggle01" data="data:image/svg xml," type="image/svg xml" ></object>
</div>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
Edit: <script>
tag in svg
You can do this MDN Example
But you'll encounter scoping issues.
If you need to call globally defined functions by clicking a svg element, you might add an eventListener after loading the object.
SVG
<svg viewBox="0 0 10 10" xmlns="http://www.w3.org/2000/svg">
<script>
// <![CDATA[
window.addEventListener('DOMContentLoaded', () => {
function getColor () {
const R = Math.round(Math.random() * 255).toString(16).padStart(2,'0')
const G = Math.round(Math.random() * 255).toString(16).padStart(2,'0')
const B = Math.round(Math.random() * 255).toString(16).padStart(2,'0')
return `#${R}${G}${B}`
}
document.querySelector('rect').addEventListener('click', (e) => {
e.target.style.fill = getColor()
})
})
// ]]>
</script>
<rect id="bg" width="100%" height="100%" fill="#ccc"></rect>
</svg>
html
<object class="svgObject" id="sidebartoggle" data="script.svg" type="image/svg xml" ></object>
js
function test(){
console.log('test')
}
var svgObject = document.getElementById("sidebartoggle");
// get svg content
svgObject.addEventListener("load",function(){
// get the inner DOM of svg
var svgDoc = svgObject.contentDocument;
var bg = svgDoc.querySelector('#bg');
// bind click event
bg.addEventListener('click', function(e){
test();
});
});
However scripts added to svg files might also be considered as suspicious in some environments (e.g. wordpress). Some file sanitizing filters will strip script tags from svg.