I am building an iframe that can be used in different domains. The iframe has a list of data, upon reaching the bottom of the scroll it updates more data.
I run into an issue where the parent window which includes the iframe has two scroll bars; my goal is to eliminate the parent scrollbar and depend on the iframe scroll or the other way around. The important part is to have one scroll for both,
My code is as follows:
<html>
<body >
<div>Header</div>
<iframe
width='100%'
height='500px'
onLoad="window.parent.scroll(0,0);"
id='iframe'
src="myIframe.com"></iframe>
<div>Footer</div>
</body>
<script type="text/javascript">
window.addEventListener('message', function (e) {
document.getElementById("iframe").height = e.data.frameHeight
});
</script>
</html>
Listening to a message from parent and setting the height of the frame, help to eliminate the iframe's scroll but I do need the that scroll to update the list when bottom is reached.
I tried some approaches but wasn't succeed. whats the best way to achieve my goal in this scenario?
Short answer
https://github.com/davidjbradshaw/iframe-resizer
Longer answer
The way the above library does it is to use MutationObserver to detect changes to the DOM in the iframe, to trigger a recalculation of the page size. The complication comes from then having to detect when images in your newly loaded html have also loaded.
function setupBodyMutationObserver() {
function addImageLoadListners(mutation) {
function addImageLoadListener(element) {
if (false === element.complete) {
log('Attach listeners to ' + element.src)
element.addEventListener('load', imageLoaded, false)
element.addEventListener('error', imageError, false)
elements.push(element)
}
}
if (mutation.type === 'attributes' && mutation.attributeName === 'src') {
addImageLoadListener(mutation.target)
} else if (mutation.type === 'childList') {
Array.prototype.forEach.call(
mutation.target.querySelectorAll('img'),
addImageLoadListener
)
}
}
function removeFromArray(element) {
elements.splice(elements.indexOf(element), 1)
}
function removeImageLoadListener(element) {
log('Remove listeners from ' + element.src)
element.removeEventListener('load', imageLoaded, false)
element.removeEventListener('error', imageError, false)
removeFromArray(element)
}
function imageEventTriggered(event, type, typeDesc) {
removeImageLoadListener(event.target)
sendSize(type, typeDesc + ': ' + event.target.src, undefined, undefined)
}
function imageLoaded(event) {
imageEventTriggered(event, 'imageLoad', 'Image loaded')
}
function imageError(event) {
imageEventTriggered(event, 'imageLoadFailed', 'Image load failed')
}
function mutationObserved(mutations) {
sendSize(
'mutationObserver',
'mutationObserver: ' + mutations[0].target + ' ' + mutations[0].type
)
// Deal with WebKit / Blink asyncing image loading when tags are injected into the page
mutations.forEach(addImageLoadListners)
}
function createMutationObserver() {
var target = document.querySelector('body'),
config = {
attributes: true,
attributeOldValue: false,
characterData: true,
characterDataOldValue: false,
childList: true,
subtree: true
}
observer = new MutationObserver(mutationObserved)
log('Create body MutationObserver')
observer.observe(target, config)
return observer
}
var elements = [],
MutationObserver =
window.MutationObserver || window.WebKitMutationObserver,
observer = createMutationObserver()
return {
disconnect: function() {
if ('disconnect' in observer) {
log('Disconnect body MutationObserver')
observer.disconnect()
elements.forEach(removeImageLoadListener)
}
}
}
}
function setupMutationObserver() {
var forceIntervalTimer = 0 > interval
// Not testable in PhantomJS
/* istanbul ignore if */ if (
window.MutationObserver ||
window.WebKitMutationObserver
) {
if (forceIntervalTimer) {
initInterval()
} else {
bodyObserver = setupBodyMutationObserver()
}
} else {
log('MutationObserver not supported in this browser!')
initInterval()
}
}
You can detect the scrollbar reached to the bottom of the page/frame and call a method which fetch data and append it to the iframe. In below example i have eliminated iframe scrollbar. And on scrolling to the bottom of the iframe, the list item will be add to the list.
<!-- added id to the header and footer ->
<div id="header">Header</div>
<iframe width='100%' id='iframe' src="test.html"></iframe>
<div id="footer">Footer</div>
/* optional, for presentation purpose only */
#header,
#footer {
height: 50px;
background-color: #f7f7f7;
text-align: center;
font-size: 24px;
font-weight: bold;
line-height: 50px;
}
// Selecting iframe
var iframe = document.getElementById("iframe");
// Adjusting the iframe height onload
iframe.onload = function() {
iframe.style.height = document.getElementById('iframe').contentWindow.document.body.scrollHeight + 'px';
}
// height of the list item going to be append
let itemHeight = 54;
function fetchListData() {
// add height to ifame for list item
iframe.style.height = document.getElementById('iframe').contentWindow.document.body.scrollHeight + itemHeight;
// append list item in a iframe Ul
$(iframe).contents().find("ul").append('<li style="height:50px;border:2px solid blue"> new item </li>')
}
$(window).on('scroll', function() {
// to get the scroll amout to reach up to bottom edge of iframe
let bottom_edge_value = $(document).outerHeight() - $(window).outerHeight() - 5;
if ($(window).scrollTop() >= bottom_edge_value) {
fetchListData();
}
});
<html>
<head>
</head>
<body >
<p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ullamcorper eros nulla, at vulputate lectus vehicula quis. Vestibulum volutpat finibus gravida. Morbi id sapien molestie, congue erat sit amet, consequat elit. Aliquam volutpat nisi a felis pharetra posuere. Aliquam varius vel sapien quis dignissim. Nam nec faucibus eros, eget volutpat orci. Vestibulum vestibulum tortor velit, ac consequat orci ornare eget.
</p>
<p>
Vivamus eleifend, nunc eget commodo sagittis, ante lorem blandit sem, facilisis mollis metus ipsum sed ex. Aenean quis felis enim. Donec sed felis sit amet risus mollis interdum. Proin commodo facilisis bibendum. Nam non accumsan tortor. Sed gravida leo ut dolor aliquet suscipit. Phasellus metus urna, lobortis et metus id, bibendum dignissim augue. Integer vehicula, ante ut efficitur iaculis, nisi mi pulvinar dui, et rhoncus nibh sem at velit. Cras vehicula massa vitae interdum rhoncus. Fusce viverra aliquam diam, ut sagittis ex ultrices in.
</p>
<p>
Fusce finibus leo tincidunt lacus gravida tincidunt. Nunc euismod molestie leo, ac imperdiet massa elementum nec. Fusce nec varius felis. Fusce ac dictum eros. Suspendisse interdum nunc tristique nisi volutpat, in congue risus dapibus. Quisque aliquam leo ut condimentum ullamcorper. Mauris vehicula, ipsum nec faucibus congue, mi ligula lacinia ipsum, ac venenatis urna urna ac nisl. Duis dui erat, dictum et dui ac, pharetra varius elit. Proin rutrum leo enim, et pellentesque nibh ultrices a.
</p>
<p>
Duis risus turpis, iaculis vel lobortis vitae, suscipit sed lectus. Curabitur varius diam a massa auctor gravida. Donec ullamcorper gravida mi, id mollis metus pretium a. Morbi egestas efficitur justo, at tincidunt quam ornare porta. Quisque nec hendrerit lacus, eu consectetur justo. Pellentesque maximus urna et odio dictum, in pulvinar magna placerat. Sed pellentesque nisl eget nunc venenatis, nec lacinia urna pulvinar. Quisque sit amet imperdiet justo. Proin aliquam, nibh eget tincidunt blandit, quam ipsum elementum nisl, id pellentesque est ipsum semper dui.
</p>
<p>
Curabitur dictum ac odio at mattis. Mauris euismod nibh tincidunt, posuere felis in, iaculis enim. Suspendisse non elit arcu. Nunc aliquet urna quis ex auctor, sed efficitur sapien porttitor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur laoreet metus commodo, tempus velit nec, volutpat diam. Mauris elit libero, tincidunt at massa eu, egestas aliquet mauris. Aliquam dignissim egestas massa, faucibus fermentum mauris commodo nec. Aliquam erat volutpat. Maecenas quis mi interdum, imperdiet nisl eu, suscipit ante. Morbi mollis dui non lectus vulputate, id tristique ipsum bibendum. Sed tempor posuere odio, euismod luctus arcu rutrum ac. Cras aliquam vel tellus id egestas. Suspendisse nec dignissim lorem, in aliquet justo.
</p>
<p>
Duis risus turpis, iaculis vel lobortis vitae, suscipit sed lectus. Curabitur varius diam a massa auctor gravida. Donec ullamcorper gravida mi, id mollis metus pretium a. Morbi egestas efficitur justo, at tincidunt quam ornare porta. Quisque nec hendrerit lacus, eu consectetur justo. Pellentesque maximus urna et odio dictum, in pulvinar magna placerat. Sed pellentesque nisl eget nunc venenatis, nec lacinia urna pulvinar. Quisque sit amet imperdiet justo. Proin aliquam, nibh eget tincidunt blandit, quam ipsum elementum nisl, id pellentesque est ipsum semper dui.
</p>
<p>
Curabitur dictum ac odio at mattis. Mauris euismod nibh tincidunt, posuere felis in, iaculis enim. Suspendisse non elit arcu. Nunc aliquet urna quis ex auctor, sed efficitur sapien porttitor. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Curabitur laoreet metus commodo, tempus velit nec, volutpat diam. Mauris elit libero, tincidunt at massa eu, egestas aliquet mauris. Aliquam dignissim egestas massa, faucibus fermentum mauris commodo nec. Aliquam erat volutpat. Maecenas quis mi interdum, imperdiet nisl eu, suscipit ante. Morbi mollis dui non lectus vulputate, id tristique ipsum bibendum. Sed tempor posuere odio, euismod luctus arcu rutrum ac. Cras aliquam vel tellus id egestas. Suspendisse nec dignissim lorem, in aliquet justo.
</p>
<ul>
<li> item 1</li>
<li> item 2</li>
<li> item 3</li>
<li> item 4</li>
</ul>
</body>
</html>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With