4

When I use the onclick attribute of an object-element in an html document, it does not respond to clicks.

In my document I have an svg image and store that in an object-element, since there is some animation in the image that would get lost by just using an img-tag.

In the simplified example below, the onmouseover works on both objects, but the onclick just works on the object without the svg-image.

document.getElementById('test1').onmouseover = hover;
document.getElementById('test1').onclick = click;
document.getElementById('test2').onmouseover = hover;
document.getElementById('test2').onclick = click;

function hover() { alert('Hovered');};
function click() { alert('Clicked');};
<object id='test1' data="https://upload.wikimedia.org/wikipedia/commons/0/01/SVG_Circle.svg" height="50px"></object>

<object id='test2' height="50px" border="1px solid black">some object</object>

Is there something I am doing wrong here? Or is there an alternative that does work?

The answers given for this (and related questions) advise to use pointer-events: none on the svg-image and wrap it in a div and apply the listeners to that div. But I need the svg-image to respond to mouse events, and therefore cannot set pointier-events: none.

Fay Boisam
  • 127
  • 4
  • 10

2 Answers2

7

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.

Asons
  • 84,923
  • 12
  • 110
  • 165
k3llydev
  • 2,057
  • 2
  • 11
  • 21
  • It is a duplicate, and for the reason `` can't have `click` event. Whether one use jQuery or plain javascript doesn't matter. – Asons May 10 '19 at 19:23
  • 1
    Furthermore, don't add such noise as telling why a question is not a dupe, just focus on answering. – Asons May 10 '19 at 19:28
3

The following code should do the trick:

<div id='test1'>
    <object style="pointer-events: none;" height="50px" data="https://upload.wikimedia.org/wikipedia/commons/0/01/SVG_Circle.svg"></object>
</div>
IceCode
  • 1,466
  • 13
  • 22
  • 1
    Thank you for the comment. If you look at my code, you can see that the object element is wrapped in a div element thus everything inside it will react to `pointer-events`. My guess is that you have not tried my code before downvoting. I hope you will try it, so you will become wiser and make stackoverflow a better place.Thanks! – IceCode May 18 '19 at 11:40
  • But the svg-image still will not react to mouse events anymore, not even to hover-events! – Fay Boisam May 18 '19 at 14:18
  • 1
    You can test the code here: https://jsfiddle.net/tvrxekbf/ – IceCode May 19 '19 at 12:45
  • I know, that your solution works for this example. But the svg image i am using, also uses javascript and css, and thereby react to mouse-events. This is not possible anymore, if pointer-events are set to none. – Fay Boisam May 19 '19 at 13:26