Change iframe height after content update - javascript

I have some tabs on my page, and inside one tab of that page I have an iframe (#quiz_iframe).
This iframe is quiz frame, which is contained in a div (.quiz-div). After hitting a button (.start-quiz), quiz is loaded, and new div (.quiz-content) appears inside (.quiz-div).
In quiz content I have 20 another divs (.quiz-question), which are paginated, so after clicking a button next, prev, you can hide or show 5 next/prev divs.
Well the point is, I'd like to adjust iframe height to that content and I don't know how, after clicking .start-quiz.
Now I have a code which works fine, when the iframe is loaded for the first time (it adjust height to the laoded content)
function iframeLoaded() {
var iFrameID = document.getElementById('quiz_iframe');
if(iFrameID) {
iFrameID.height = "";
iFrameID.height = iFrameID.contentWindow.document.body.scrollHeight + "px";
}
}
<iframe onload="iframeLoaded()" id="quiz_iframe" src="'.$link.'" style="width:100%;"></iframe>'
How I can modify that code, to update iframe height on every .quiz-div height change? And yes, iframe is in the same domain :)
Thanks!

You can use a solution based on postMessage
You'll have to include some JavaScript in the iframe and on the parent page as well.
In your iframe :
window.addEventListener("load", function() {
parent.postMessage(getDocumentHeight(), "*");
});
In your parent page :
function receiveIframeHeight(frameWindow, height) {
$("iframe").each(function () {
if (this.contentWindow === frameWindow) this.height = height;
});
};
window.addEventListener("message", function (e) {
receiveIframeHeight(e.source, e.data);
});
You can now listen to the resize event and postMessage from your iframe to the parent page. But beware of infinite loop.
To see the whole code you should take a look at this Github repo iframe-autoheight-using-postmessage

In jQuery, you could use
$("myContainer .quiz_div").on("resize", function () {
$("#quiz_idrame").attr("height", your height calc goes here);
});
The "on" is a delegated event binding and thus if you add/remove items with the class of .quiz_div to the "myContainer" i.e. whatever contains the divs, it should bind.

Related

Detecting weather user scrolls the bottom of the div or not in react js and javascript

I want to implement infinite scrolling in the table, so I am calculating div height in one possible way, you can see below
let fixedCh = e.target.clientHeight;
let calCh = e.target.scrollHeight - e.target.scrollTop;
if (fixedCh === calCh) {
alert('load more');
}
In this approach,calCh is varied from different resolutions. Is there any other way of doing this, so that it can work through all kind of browser and screen resolution
Your approach is good; you need to call your function initially when the user loads the page to check if the user's screen resolution is already to the end of the scroll, call "alert('load more')".
The problem is that for some users, based on their screen, the scrollbar will not be visible to scroll, so your event of scroll won't check the element. To fix this, as I said above, you need to initially load your screen check function when the "Dom is ready".
Here is the basic implementation:
function loadMore (e) {
let fixedCh = e.clientHeight;
let calCh = e.scrollHeight - e.scrollTop;
if (fixedCh === calCh) {
alert('load more');
}
}
// listen on scroll and check target element fixedCh === calCh
function listenOnScroll() {
document.getElementById('app').addEventListener('scroll', (e) => {
loadMore(e.target)
})
},
window.onload = (event) => {
loadMore(document.getElementById('app').target)
};
I will call the function "loadMore" when the dom is ready or loaded and pass the targetted Dom element.
Later, I'll call the "listenOnScroll" function to listen on the target element scroll and then call the "loadMore" function from it.

JavaScript - Event listener with window.matchMedia not triggering

I've panned through countless solutions to this problem and none of them have fixed my issue. I very simply have a navigation bar, which, when on a mobile browser, disappears and becomes replaced with a button, whose function is to show and hide the navigation bar.
Now, I want my listener to, when the window is shrunk, show the button and hide the navigation bar. When the window is expanded, the button should be hidden and the navigation bar should be shown. The button is working as it should be, since the media query doesn't affect it. My listener appears to not run at all, except when the page is reloaded.
My script is contained inside of a PHP header which is included at the beginning of all my pages. Here's what I've got:
Media Query Listener (contained in header.php code)
// ... navbar code, opening script tag, yadda yadda
function mediaQueryCheck(inputQuery) {
var content = document.getElementById("navigation");
if (inputQuery.matches) {
// it matches
content.style.display = "none";
} else {
// it does not match
content.style.display = "block";
}
}
var mobileQuery = window.matchMedia("screen and (max-width: 638px)");
mediaQueryCheck(mobileQuery);
mobileQuery.addEventListener(mediaQueryCheck);
// closing script tag
The element #navigation is a div element containing the navigation bar. I will provide any other relevant code, if necessary.
Using addListener instead of addEventListener fixed the problem.
for whoever needs another solution:
you may use this function:
function getWidth() {
var maxWidth = Math.max(
document.body.scrollWidth,
document.documentElement.scrollWidth,
document.body.offsetWidth,
document.documentElement.offsetWidth,
document.documentElement.clientWidth
);
console.log(maxWidth); // for testing only
if(maxWidth === 776){
//do sth
}
if(maxWidth === 992){
//do sth
}
return maxWidth;
}
window.addEventListener("resize", getWidth);
now you have the width of the screen all the time
this is just another way of doing things... you may wanna use whatever serves your purpose.
You have to check it every time, when window is resized.
window.addEventListener('resize', function(){
mediaQueryCheck(mobileQuery);
});

2 window.parent.onscroll calls on page do not work

I have an HTML page with 2 iframes within it. I want each iframe to display the Y scroll offset of the parent window. One iframe works on page load, the other does not.
The parent HTML page just has the iframe embeds. Here is the code running in the iframe:
function run(){
document.write("<div id='scrollY' style='float:left;'></div><br>");
scrollY = 'no';
document.getElementById("scrollY").innerHTML = scrollY;
window.parent.onscroll = function(){
scrollY = window.parent.pageYOffset;
document.getElementById("scrollY").innerHTML = scrollY;
}
}
run();
The result on load and a scroll downwards will display something like:
iframe1 = 100
iframe2 = no
Can I only call window.parent.onscroll once? This doesn't seem right to me.
This is happening because in both frames, window.parent makes reference to the same window object, and you are setting the onscroll property/event on the same object, twice. This means that the second time around you set the window.parent.onscroll property, you're actually overwriting the first attempt to set the event, and you're overwriting it with the second frame's window.document object, which is why it only updates the contents of the elements in the second frame.
To overcome this issue, you can simply just use addEventListener instead of onscroll:
http://jsfiddle.net/x046o0p7/
function run() {
document.write("<div id='scrollY' style='float:left;'></div><br>");
scrollY = 'no';
document.getElementById("scrollY").innerHTML = scrollY;
window.parent.addEventListener('scroll', function() {
scrollY = window.parent.pageYOffset;
document.getElementById("scrollY").innerHTML = scrollY;
});
}
addEventListener allows you to set multiple events of the same type for the same element, while the .onstuff listeners don't.

Removing iframe from page

I am creating an iframe dynamically for submmiting a form,after submitting i need to remove the iframe form the page.I removed itas follows but it is not removed,
function remove(){
var frame = document.getElementById("upload_iframe"),
var frameDoc = frame.contentDocument || frame.contentWindow.document;
frameDoc.removeChild(frameDoc.documentElement);
}
How to remove the ifarme form the form completely.
Thanks
Frame has 2 behaviors: frame as document element (like div or another DOM element) and frame as window element (like global window object). So if you want to remove iframe from DOM tree you have to work with iframe like with DOM element
function remove(){
var frame = document.getElementById("upload_iframe");
frame.parentNode.removeChild(frame);
}
A way I've been doing it (since I have a large amount of iframes) is using jQuery,
$('iframe').remove()
or in the case of only one iframe you can remove it using its ID, still with jQuery
$('#iframeID').remove()

Resize iframe on content refresh or update

I have an iframe that I would like to resize to match its contents whenever the contents auto refreshes (every few minutes) or when the user interacts with it. Although the contents are in the same domain, it would be difficult for me to modify the contents. Ideally, the iframe would just self adjust to the size of its contents.
Current code that resizes only once:
<iframe id="ganglia-frame" src="ganglia.url" width="100%" height="500%">
blah not supported blah
</iframe>
<script language="Javascript">
function setIframeHeight(iframe) {
if (iframe) {
var iframeWin = iframe.contentWindow ||
iframe.contentDocument.parentWindow;
if (iframeWin.document.body) {
iframe.height =
iframeWin.document.documentElement.scrollHeight ||
iframeWin.document.body.scrollHeight;
}
}
}
$(window).load(function () {
setIframeHeight(document.getElementById('ganglia-frame'));
});
</script>
Related question: Adjust width height of iframe to fit with content in it
What you need to do is to set a timer and check the iFrame size after a few moments. You may have to check several times as not all browsers return the correct size immediately.
This method works only on same-domain iFrames.
Bind a function to the iFrame onload event and when it executes check the height of the iFrame. If no height is found schedule another check in a few moments.
var iFrameSizeCount = 0;
var onloadFunction = function(event){
var contentHeight = document.getElementById('iFrameId').contentWindow.document.body.offsetHeight;
if(contentHeight == 0){
// Schedule a recheck in a few moments
iFrameSizeCount++; // we keep a count of how many times we loop just in case
if(iFrameSizeCount < 10){ // after a while we have to stop checking and call it a fail
setTimeout(function(){ onloadFunction(event); }, 200);
return false;
}
else {
contentHeight = 100; // eventually if the check fails, default to a fixed height. You could possibly turn scrolling to auto/yes here to give the iFrame scrollbars.
}
}
contentHeight += 30; // add some extra padding (some browsers give a height that's slightly too short)
document.getElementById('iFrameId').style.height = contentHeight + 'px';
}
Then bind the event to the onload event of your iFrame (however you want to):
The "scrolling=auto" is useful, just in case the sizing fails at least they have scrollbars. The onload event fires if the iFrame reloads, so is useful if they've clicked a link inside it.
I have had good luck with this jQuery plugin - https://github.com/davidjbradshaw/iframe-resizer

Categories