iframe-resizer
iframe-resizer copied to clipboard
Anchor scroll to incorrect positioning
When using anchors on the iframed page, their positioning seems to be off by the number of pixel between the top edge of the containing page and the edge of the iframe (offsetTop)
I clicked on the "G" anchor and landed about 50px lower on the "H"
Hi, I was wondering if anyone has experience this issue and found a solution. I implemented a solution using messaging to relate the offset back to the parent once the iFrame completes loading and then execute a scrollBy on the parent with that offset. However, it a very laggy and the little jump at the end is quite distracting. Does anyone have a better solution to this issue? Thanks
That's strange, have you tried to see if you can reproduce this in the example folder?
The function in the code that does this can be found here, if you want to dig deeper https://github.com/davidjbradshaw/iframe-resizer/blob/94cb6ba4fb0d7c784e678f00f97d0109b6ecaf11/src/iframeResizer.js#L395
Thanks David. I will investigate further and let you know. I was not able to replicate with the examples. It may have something to do with the sticky header on the page hosting the iFrame
I have a question about the calculation of offsetTop
that may be related. This number is calculated as the difference between the top of the <body>
and the top of the <iframe>
(https://github.com/davidjbradshaw/iframe-resizer/blob/master/src/iframeResizer.js#L316). I'm curious, why not just read the offsetTop
property of the iframe?
The hosting page on my website has a sticky header as well, and recently the owners of that page switched from using top padding to using top margin on the body content to clear that header when the page is scrolled to the top. When using padding, the top of the body is above the top of the iframe by a distance equal to the height of the padding. But when using margin, the top of the body and the top of the iframe are equal since margin is rendered outside of the bounding box of an element. Thus, the value of offsetTop
changes even though the iframe's position in the layout has not changed.
Good question, I guess that was written seven years ago, so what ever the reason might not be valid anymore
Hey @gmferland, just wondering if you were ever able to get that sticky header on top of the iframe to work. I am attempting the same thing and would appreciate any insight you already learned.
Hey @ryanzhou7, due to the fact that we were serving up our own minified version of the library (rather than getting it from a cdn or npm), we were able to make changes directly in the source code. We went ahead and implemented the change I suggested in my previous comment, and it's been working well
Hey @gmferland we ended up not using the sticky header, but thanks for replying!
Just a heads up here that we also ended up applying the fix from gmferland above. The offsetTop is more reliable in the presence of headers with fixed positioning.
We have seen situations where offsetTop is zero, when it is certainly not, so the original code was favorable. Working with this customization in place now:
if(typeof(messageData.iframe.offsetTop) !== 'undefined' && messageData.iframe.offsetTop !== 0){
iFrameOffsetTop = parseInt(messageData.iframe.offsetTop, 10);
}else{
iFrameOffsetTop = parseInt(iFramePosition.top - bodyPosition.top, 10)
}
@metalocator I'm thinking of completely rewriting this in v5 along the lines of the following and wonder what your thoughts are?
function getPageInfo() {
const { iframe } = messageData
const { innerHeight, innerWidth, scrollY, scrollX } = window
const { scrollWidth, scrollHeight } = document.documentElement
return JSON.stringify({
iframe: iframe.getBoundingClientRect(),
scroll: {
height: scrollHeight,
width: scrollWidth,
x: scrollX,
y: scrollY
},
window: { innerHeight, innerWidth }
})
}
The existing function is the product of one too many PRs and a bit of a mess. I'm thinking it might be time to go back to the drawing board on this one.
@metalocator I just saw the sponsorship, thank you.
Just decided to give the new version a different method name and add a deprecation warning to the old version.