Issue
I have an HTML document which, towards its bottom, contains an iframe.
In this case, the iframe embeds a Google Spreadsheet, with the code:
<iframe id="gsheet-group" width="100%" height="400" src="https://docs.google.com/spreadsheets/d/<!----DOCUMENT_KEY----->/edit?usp=sharing&rm=minimal&gid=0&single=true&widget=false&chrome=false&headers=false">Loading sheet..</iframe>
I believe that this iframe contains some javascript that causes its parent window to scroll to the top on certain events, such as when its loading is complete or its content is navigated in certain ways. (This behaviour persists if the iframe is embedded within a second iframe.)
If I can't directly modify the source code of the iframe, can I prevent a parent window from being manipulated by javascript in iframe-embedded content?
What I've tried
I'm grateful to the commenters for suggestions, none of which have sadly solved the problem:
- Adding
sandbox="allow-scripts allow-forms allow-pointer-lock allow-same-origin"
to the<iframe>
element (to removeallow-top-navigation
; @CBroe). - Overriding
window.scrollTo
(@Ryano) - Putting the iframe in a separate iframe (@Ryano)
Solution
One such API that would allow even cross-origin iframes to scroll the top document is Element#scrollIntoView()
. I didn't check it's really what your embedded page was doing, but that sounds like a very plausible explanation.
Here is a minimal example. To reproduce:
- Run the snippet
- Immediately scroll to the top of the page manually.
- Wait about 2s for the snippet scrolls back to view automagically:
(You can also click in the result iframe to call scrollIntoView again, 2s later).
onclick = e => setTimeout(() => {
document.body.scrollIntoView();
}, 2000);
onclick();
Scroll to the top of the top page and wait 2s.
After digging the specs I'm afraid there is no out-of-the-box solution to prevent this behavior...
One noticeable thing though is that Chrome will not scroll to fixed elements in an iframe. This means that we can actually hack-around this bug to define a "scroll-stop" layer: You can wrap the target iframe in an other iframe, set this inner iframe's position to fixed and so that it covers entirely the wrapping iframe. This will prevent Chrome from scrolling this iframe's ancestors:
iframe { position: fixed; top: 0; width: 100vw; height: 100vh; border: none; padding: 0; margin: 0; }
<iframe srcdoc="
<script>
onclick = e => setTimeout(() => {
document.querySelector('h1').scrollIntoView();
}, 2000);
onclick();
</script>
<h1 style='margin-top: 100vh' >I still scroll into view, but not the top page.</h1>
"></iframe>
However this is a complete hack-around, it's basically a bug exploit, it obviously doesn't work in other web-browsers and it may even fail in a future version of Chrome, if they fix the issue.
But that's the only thing I could find for now.
What I invite you to do though is to make your point over at W3C's CSS working group's Github repo so that they consider adding a property that would allow this feature officially.
Answered By - Kaiido Answer Checked By - David Goodson (PHPFixing Volunteer)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.