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

前端 未结 5 1806
误落风尘
误落风尘 2021-01-01 10:22

I have an iframe with an inherited pointer-events: none; but when I have inserted a

inside the iframe with a pointer-events: auto
相关标签:
5条回答
  • 2021-01-01 10:43

    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.

    0 讨论(0)
  • 2021-01-01 10:47

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

    0 讨论(0)
  • 2021-01-01 10:52

    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.

    0 讨论(0)
  • 2021-01-01 10:57

    Have you tried this?

    pointer-events: inherit;
    

    I know you already got your answer, but I thought this might work, too.

    0 讨论(0)
  • 2021-01-01 10:59

    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.

    0 讨论(0)
提交回复
热议问题