How can I disable clicks but still allow scrolling in an iframe?
Asked Answered
C

2

22

I have an iframe showing on my page in a panel of a fixed height but the page rendered in the iframe is much larger. I don't want the user to be able to click on anything in the iframe. I know that the general solution to this would be to have an invisible div on top of the iframe to disable all interaction. However, this also disables the ability to scroll. Is it possible to catch and ignore any clicks on the iframe page but still allow the scroll to be propagated?

Chaucerian answered 26/4, 2017 at 3:54 Comment(8)
Guessing the iframe is not in your domain.Uncommitted
No, not in my domainChaucerian
Than there really is nothing you can do. You can guesstimate the height of the page and set your iframe to that full size and than scroll a div on your page.Uncommitted
Incorrect, there is tonnes you can do. Simpy inject your own javascript into the domain and assuming you have jQuery enabled you can just use something like $('button').click(function(){}) and similar functions to disable the events fired by all the interactive elements of a website.Runnymede
I don't think you can inject javascript cross domain like that.Chaucerian
I was thinking something more along the lines of catching scroll event on overlayed panel and then programmatically send that scroll event to the iframe element. That way it can be done without any inner knowledge or access to the iframe pageChaucerian
You can add script tags to the target iframe, at least according to this: #1591635. And if that is incorrect I can probably create an example of manipulating an iframe for you but it would take some time and I'm really tired right now...Runnymede
api.jquery.com/scroll If you want to grab scroll you can do it with jquery, then set the scroll value of the iframe to match the scrolling amount. api.jquery.com/click Simply do $('iframe').children().click(function () {}) and it should make all clicks on anything in the iframe be useless.Runnymede
E
23

If you don't want the contents of the iframe to be interactable by the user, you can disable pointer-events on it. But as you want it to be scrollable, just put a full sized iframe in a smaller div with overflow: scroll.

div {
  width: 50vw;
  height: 50vh;
  overflow: scroll;
}

iframe {
  width: 100vw;
  height: 100vh;
  pointer-events: none;
}
<div>
  <iframe src="http://example.com"></iframe>
</div>
Edholm answered 26/4, 2017 at 11:57 Comment(2)
The problem here is that the iframe can be arbitrary height so there's no value for what a "full sized" iframe would be. I could set the iframe to be overly large but then that just gives a lot of empty space at the bottom which looks bad.Chaucerian
This works in theory but needs a "magic number" to work. The 100vh for the iframe height will be 100% of the parent, not the iframe.Dibrin
S
0

As a follow up to this thread, is there a way to get this iframe to dynamically update to the size of the src page?

Currently I use a magic number of 1000vh to display the google doc, but I'm trying to figure out how to set it so that it will dynamically become only the length necessary (e.g. 500vh, 750vh, etc.). I've tried implementing it in React, but can't figure out how to update the iframe height style attribute accordingly.

For context, I'm using a Custom Component in ReTool.

<style>
  div {
    width: 100%;
    height: 100%;
    overflow: scroll;
  }
  
  iframe {
    width: 100%;
    height: 1000vh;
    pointer-events: none;
  }
</style>

<!-- You can add any HTML/CSS/JS here. UMD versions are required.
Keep in mind that Custom Components are sensitive to bundle sizes, so try using a
custom implementation when possible. -->
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>

<div id="react"></div>

<script type="text/babel">
  // Function to create the iframe element
  function createIframe(fid) {
    return <iframe src={`https://docs.google.com/document/d/${fid}/edit?usp=sharing`}></iframe>;
  }

  // Function to create the div element containing the iframe
  function createDiv(fid) {
    return <div>{createIframe(fid)}</div>;
  }

  // Main React component
  const MyCustomComponent = ({ model }) => {
    
    return createDiv(model.fid);
  }

  // This is the entrypoint for the React component.
  const ConnectedComponent = Retool.connectReactComponent(MyCustomComponent)
  const container = document.getElementById('react')
  const root = ReactDOM.createRoot(container)
  root.render(<ConnectedComponent />)
</script>
Sprinkle answered 18/6 at 10:37 Comment(1)
If you have a new question, please ask it by clicking the Ask Question button. Include a link to this question if it helps provide context. - From ReviewLudovika

© 2022 - 2024 — McMap. All rights reserved.