Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can you make an iframe have pointer-events: none; but not on a div inside that?

Tags:

html

css

iframe

I have an iframe with an inherited pointer-events: none; but when I have inserted a <div> inside the iframe with a pointer-events: auto; the div won't react to clicks or any mouse hover events.

The reason for this is that the iframe is inside a <div style="position:fixed;"> so it is kind of like a little menu. but I would like the user to click through the iframe, but not through the links and divs in the iframe.

And yes, it absolutely needs to remain an iframe.

How could I bypass this? Can I even bypass this?

Here's a simple example: jsfiddle.net/MarcGuiselin/yLo119sw/2

like image 808
Marc Guiselin Avatar asked Apr 27 '14 22:04

Marc Guiselin


People also ask

Can an iframe show only part of page?

Set the iframe to the appropriate width and height and set the scrolling attribute to "no". If the area you want is not in the top-left portion of the page, you can scroll the content to the appropriate area. Refer to this question: Scrolling an iframe with javascript?

How do I change cursor with pointer-events none?

Using pointer-events: none will disable all mouse interactions with that element. If you wanted to change the cursor property, you would have to apply the changes to the parent element. You could wrap the link with an element and add the cursor property to it.


2 Answers

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");

like image 136
Kamae Avatar answered Sep 18 '22 21:09

Kamae


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.

like image 21
troy Avatar answered Sep 17 '22 21:09

troy