This is very late, but I was wondering why energee's solution works: specifically, how the <object>
element affects its parent elements.
tl;dr You cannot click on an anchor that has an <object>
element in it because the click events are being captured by whatever is inside of the <object>
element, which then doesn't bubble it back out.
jsfiddle
To expand on the symptom described in the original question: not only will an <object>
element inside an anchor element cause the anchor to become unclickable, it seems that an <object>
element as a child of any element will cause click
, mousedown
, and mouseup
events (possibly touch events too) to not fire on the parent element, (when you are clicking inside the <object>
's bounding rect.)
<span>
<object type="image/svg+xml" data="https://icons.getbootstrap.com/icons/three-dots.svg">
</object>
</span>
document
.querySelector('span')
.addEventListener('click', console.log) // will not fire
Now, <object>
elements behave somewhat "like" <iframe>
s, in the sense that they will establish new browsing contexts, including when the content is an <svg>
document. In JavaScript, this is manifested through the existence of the HTMLObjectElement.contentDocument
and HTMLObjectElement.contentWindow
properties.
This means that if you add an event listener to the <svg>
element inside the <object>
:
document
.querySelector('object')
.contentDocument // returns null if cross-origin: the same-origin policy
.querySelector('svg')
.addEventListener('click', console.log)
and then click on the image, you will see the events being fired.
Then it becomes clear why the pointer-events: none;
solution works:
Without this style, any MouseEvent
that is considered "interactive" (such as click
and mousedown
, but not mouseenter
) is sent to the nested browsing context inside the <object>
, which will never bubble out of it.
With this style, the MouseEvent
s aren't sent into the <object>
in the first place, then the <object>
's parent elements will receive the events as usual.
This should explain the z-index
solution as well: as long as you can prevent click
events from being sent to the nested document, the clicking should work as expected.
(In my test, the z-index
solution will work as long as the parent element is not inline
and the <object>
is positioned and has a negative z-index
)
(Alternatively, you can find a way to bubble the event back up):
let objectElem = document.querySelector('object')
let svgElemt = objectElem.contentDocument.querySelector('svg')
svgElem.addEventListener('click', () => {
window.postMessage('Take this click event please.')
// window being the outermost window
})
window.addEventListener('message', console.log)