I have an iframe with an inherited pointer-events: none;
but when I have inserted a pointer-events: auto
Don't give the whole iframe pointer-events: none
. Just inside the iframe
put a CSS rule body * { pointer-events: none;}
This way the iframe does not block events, however elements inside the iframe are not clickable.
You're working with position:absolute
, according to the example you've uploaded on jsfiddle... Adding a z-index
to the "you can't click me because i'm behind the iframe" button allows me to click it.
Z-Index
EDIT: If you want to do a pointer-events: none;
everywhere except in one div
, you can add the pointer-events
in each element
instead of the iframe
. According to your example in the fiddle, if you want to save the Nicholas Cage but block the other events, you can do something like this:
switchbutton.onclick=function(){
this.innerHTML="reload to reset";
//iframe.style.pointerEvents="none";
cantclick.innerHTML="You can click me now! :)";
iframe.contentDocument.body.innerHTML="<button>You can't click me now because my parent iframe is click-through! :(</button><br>or save this gorgeous image of your favorite actor which may or may not be relavant to the problem.<br><img id='nicholasCage' src='http://media2.popsugar-assets.com/files/2014/01/06/008/n/1922283/131b4126c7b8738f_thumb_temp_image333458751389045360.jpg.xxxlarge/i/Best-Nicolas-Cage-Memes.jpg'/>";
var iframeBody = iframe.contentDocument,
elements = iframeBody.querySelectorAll("*"),
i,
len = elements.length;
for(i=0;i<len;i++){
elements[i].style.pointerEvents="none";
}
iframeBody.getElementById("nicholasCage").style.pointerEvents="all";
}
If you can use jQuery you can do it faster just using $("iframe *").css("pointer-events","none");
I've searched a lot and figured out a workaround myself.
// the iframe element
const frame = document.getElementsByTagName("iframe")[0];
frame.onload = function () {
const frameDocument = frame.contentDocument;
document.addEventListener("mousemove", onMouseMove, true);
frameDocument.addEventListener("mousemove", onMouseMove, true);
function onMouseMove(e) {
let coord;
if (e.currentTarget === document) {
coord = {
x: e.pageX - frame.offsetLeft,
y: e.pageY - frame.offsetTop,
};
} else {
coord = { x: e.clientX, y: e.clientY };
}
const el = frameDocument.elementFromPoint(coord.x, coord.y);
// you can compare to your own element if needed
frame.style.pointerEvents = !el || el === frameDocument.body ? "none" : "auto";
}
};
The iframe will auto toggle its pointer-events
and all events just works seamlessly.
Have you tried this?
pointer-events: inherit;
I know you already got your answer, but I thought this might work, too.
There's no way you can do it, since it would be another security issue along with clickjacking.
Styles inside iframe don't cooperate in any way with styles inside of host site. So if you even set z-index/pointer-events or something else on iframe and would try to override the rule inside of it, it won't apply to host site rules in any way.
So what's the solution? You have to split your iframe into multiple ones, and tinker with theirs position.