Home > other >  Onclick event on Object HTML Tag doesn't work, workaround?
Onclick event on Object HTML Tag doesn't work, workaround?

Time:11-16

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 &lt;object&gt; – 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.

  • Related