I have a web page that is hosted in an iframe. I can only modify this page and not the containing page.
By default, my page's scrollbar is disabled, however if my page's size is over a certain threshold, I need to be able to turn on the vertical scrollbar. The following code seems to work in all browsers but Firefox:
function getDocHeight() {
var D = document;
return Math.max(
Math.max(D.body.scrollHeight, D.documentElement.scrollHeight),
Math.max(D.body.offsetHeight, D.documentElement.offsetHeight),
Math.max(D.body.clientHeight, D.documentElement.clientHeight)
);
}
function setScrollbar() {
if (getDocHeight() > 5000) {
pageBody.style.overflow = 'scroll';
}
}
here is my HTML:
<html xmlns="http://www.w3.org/1999/xhtml" >
<head><title>My title</title></head>
<body id="pageBody" onload="setScrollbar();">
</body>
</html>
Firefox seems to be ignoring the style.overflow = 'scroll'. I've done a good bit of searching, and I can't seem to find a solution. Any ideas?
Replace this:
pageBody.style.overflow = 'scroll';
with this:
document.getElementById('pageBody').style.overflow = 'scroll';
When I've checked your code in FF I was getting JS error pageBody is undefined, that should solve the issue :)
Cheers
G.
style.overflow = 'auto' should work better. It makes the browser decide when to add scroll bars itself.
Unfortunately Firefox displays the scrollbars on the body of a frame based on the overflow style on the frame, not on the body. So the easiest way is to insert a 100% size borderless scrollable subframe, and load the real content in there instead.
If you don't want to do that, then you can mess around with nested DIVs like this:
<body style="margin: 0px;"> <!-- override default body margin -->
<div style="height: 100%; overflow: auto;"> <!-- The actual scrollable area -->
<div style="margin: 8px;"> <!-- to emulate default body margin -->
<!-- Content goes here -->
</div>
</div>
</body>
Related
Chrome v75 appears to have introduced a bug whereby if you replace an iFrame's src programatically, it will replace the entire page instead of the iFrame.
This didn't happen on v74 and I can't get a test case to work (yet), it just fails in our site. (The site hasn't changed since going from v74 to v75, only Chrome has changed)
It appears to work fine the first time but then when you change it again (in our case viewing report drill downs) it causes the entire page (i.e. the iFrame's Parent) to load the src you were trying to load into the iFrame.
It also doesn't matter if you use pure Javascript or (in our case) JQuery, both cause the same issue.
EDIT: After a few hours detective work, I've found the bug. Setting the tag in the iFrame's content causes Chrome to load the iFrame's content into it's parent rather than the iFrame itself.
I've setup a Plunker account with a demo: https://plnkr.co/edit/UQ0gBY?plnkr=legacy&p=info
Just so I can post the link to Plunker, here is the code for the main file & the iframe content
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script>
function onLoaded() {
// find element
let button = document.getElementById("button");
button.addEventListener("click",function(e){
// Add a random number on the end as a cache buster
document.getElementById('frame-finance-custom').src = 'test2.html?rnd=' + Math.random();
},false);
};
document.addEventListener('DOMContentLoaded', onLoaded, false);
</script>
</head>
<body>
<div>IFrame Src Changing Test</div>
<div>
<div id="div-frame-finance-custom" style="float:left;width:33%">
<iframe id="frame-finance-custom" name="frame-finance-custom" class="iframe"
style="border:1px solid black; width: 100%; height: 350px; overflow-y: scroll; vertical-align: top;">
no data
</iframe>
</div>
<div style="float:left;margin-left:1em;">
Detail: Loading an iframe page with a <Base> tag in it with target set to "_parent" will cause any refresh of that frame to replace the parent document<BR>
<BR>Instruction: <UL><LI>Click the 'Update Frame' Button, this will load test2.html into the frame. <LI>Click it again & it will replace the iframe's parent with the content of the iFrame.</UL>
<BR>Confirmation: Remove the <Base> tag from the header of test2.html & reload, it will work as expected.
</div>
</div>
<br clear=both>
<div>
<button id="button">
Update Frame
</button>
</div>
</body>
</html>
IFrame Content (test2.html):
<!DOCTYPE html>
<html lang="en">
<head>
<base target="_parent"/>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div>This is the frame content</div>
</body>
</html>
Note, using their new layout it doesn't work, but using their legacy layout it does. Feel free to save the files locally and use chrome directly too.
Ok, so this turned out to be a bug in Chrome rather than anything else, so yes, strictly not a SO question, but seeing as SO ranks so well in Google (other search engines are available), I thought it better to leave it here as a solution rather than simply delete it, just incase anyone else has a similar problem.
The reason is outlined as an edit in my question, the solution is to remove the <base target="_parent"> tag from the iFrame and programatically add the 'target="_parent"' attribute to any links in the iFrame.
We do this via jQuery, I'm sure its just as easy via vanilla Javascript.
$('a').attr('target','_parent');
Add that to the javascript that runs when a page has loaded and it'll replace add target="_parent" to any links on the page.
e.g.
<script>
function onLoaded() {
// find all links and add the target attribute
$('a').attr('target','_parent');
};
document.addEventListener('DOMContentLoaded', onLoaded, false);
</script>
As #Kaiido says in his comment, its apparently fixed in Chrome v77, but this isn't the current (as of June 2019) stable release, so we've had to add the workaround into production so that our CRM works with Chrome v75. Thanks to #Kaiido for confirming that.
I created a HTML page with several text paragraphs in it. I wanted it to automatically scroll bottom after opening the page. So I used following Javascript and it working fine. let say it is page.html
But then I needed it to display inside an iframe. Let say main page as index.html, index.html has iframe tag: <iframe src="./page.html"></iframe>
It also worked while loading inside the iframe within major browsers (chrome, firefox, IE, Opera) but not in Apple's Safari mobile browser.
I tested direct HTML page page.html with Safari mobile browser and it worked!
But after loaded same page inside an iframe in index.html it didn't work.
This is the Javascript I have used in page.html
<script language="javascript">
function autoScrolling() { window.scrollTo(0,document.body.scrollHeight); }
setInterval(autoScrolling, 1000);
</script>
Please suggest me a code fix for Apple's Safari mobile browser
You need to use -webkit-overflow-scrolling: touch, example:
<div style="overflow: scroll !important; -webkit-overflow-scrolling: touch !important;">
<iframe ...> ... </iframe>
</div>
you have to use -webkit-overflow-srolling: touch on the parent of the iframe, and set a height for your iframe.
<style>
.parent-iframe {
-webkit-overflow-srolling: touch;
overflow-y: auto;
}
iframe {
height: 100vh
}
</style>
<div class="parent-iframe">
<iframe src="http://someurl.com ...>
</div>
Also if you have some position: fixed elements in your iframe they will not be fixed on ios safari. You can try this solution to avoid that:
https://github.com/PierBover/ios-iframe-fix
I am creating a new popup window and I want to scroll my page to specific location, I tried all three methods I mentioned on top but none of them is not working.
Here is my code
var w = window.open('','TEST','width='+divWidth+',height='+divHeight+'');
w.onload = function() {
w.scroll(200,300);
};
Any idea?
Gokhan, my guess is that the window's body is empty, yielding a content size of zero. Since the dimensions of the content are 0 width by 0 height, the window's viewport effectively collapses to nothing -- essentially reducing scroll() (and friends) to a noop.
I put together a little fiddle to demonstrate that having sufficient content fixes the problem. http://jsfiddle.net/blangenfeld/SXnA8/3/
UPDATED ANSWER
Okay, now I understand that you're creating a pop-up using content from a same-origin page. Try defining an onload for the pop-up window and doing your scrolling there.
<html>
<head>
<style type="text/css">
/* Just ensuring the size of the content for demo purposes */
body { min-width: 500px; min-height: 500px;}
</style>
<script type="text/javascript">
function showPopUp(url) {
popUp = window.open(url, "_blank", "width=300, height=300");
/* This works if the URL doesn't violate same-origin policy */
popUp.onload = function() {
this.scrollTo(100, 100);
}
};
</script>
</head>
<body>
<h1>Pop-up test</h1>
<a href="#" target="_blank" onclick="showPopUp('popup.html');">
Click for a same-domain pop-up
</a>
|
<a href="#" target="_blank" onclick="showPopUp('http://www.google.com');">
Click for a google.com pop-up
</a>
</body>
</html>
I have two sites that I am sort of melding together. I'm using and iframe to display content from one page in the other as if it were all one site. The caveat here is that I need the page to display as normal when viewed in an iframe and to display a warning otherwise. I cannot import the iframe page into the host page due to IIS incompatibility so that option is out. The plan works fine when I simply display the page under all circumstances, it is when I try to implement the conditional display that I run into problems. On the iframe page I have the following:
<script type="text/javascript">
window.onload = function InFrame() {
MainContent_siteIsNotFramed
if (top != self) {
//document.getElementById("siteIsFramed").style.display = "inline"
siteIsFramed.visible = "true"
}
else {
//document.getElementById("MainContent_siteIsNotFramed").style.display = "inline"
siteIsNotFramed.visible = "true"
}
init();
};
</script>
This is my attempt to get the iframe page to handle its own conditional display. The only relevant code I have in the host page is the iframe itself which, for completelness, looks like this:
</head>
<body style="margin:0; height: 100%;">
<iframe runat="server" id="signInFrame" style="border: 0; width: 100%; height: 100%; ">
Your browser does not support iframes. Consider upgrading.
</iframe>
</body>
</html>
When the content to display/not display, the content in the iframe will display with about half height. Without, it displays at full height (desired behavior). I've tried to be as thourough as possible, if anyone needs more details, let me know.
Try "positioning" the iframe:
<iframe runat="server" id="signInFrame" style="border: 0; position:absolute; width: 100%; height: 100%; ">
Your browser does not support iframes. Consider upgrading.
</iframe>
The problem is that and iframe with default position (position: static) can't have a "relative" height (i.e. a %), so it ignores the height:100%, and applies the "default" height of an iframe (150px in FF).
So, if I understand http://api.jquery.com/offset correctly, $('body').offset() should return the position where the body is located, relative to the document. So inserting a <p>-tag at those coordinates on the page should put it at the very position of the body tag. But that is not what happens!
I tried this in both Safari 5.0.5 and Firefox 3.6 and both cases, the alert says "8" and the <p>-tag ends up 8 pixels from the top of the page, whereas the body tag starts 100 pixels further down on the page, as can be seen if inspecting using e.g firebug.
<!doctype html>
<html>
<head></head>
<body>
<div style="margin-top:100px;background:yellow;">
<p>Hello World</p>
</div>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js">
</script>
<script>
alert(jQuery('body').offset().top);
var myp = jQuery('<p>Top of body?</p>')
myp.appendTo(jQuery('body'));
myp.offset(jQuery('body').offset());
</script>
</body>
So the question is: how am I supposed to do this so that the <p>-tag ends up in the body, and not at the top of the page, using .offset()?
In most cases you'll find the body offset is equal to 0, that is because the body of the page is == you browsers viewport.
The reason Hello World is 100px down, is because you've applied a padding to it. Do you want your text "Top of body?" to appear below Hello World?..
If so, first give your div a class name (I've used hworld) and then append your var to it.
<div style="margin-top:100px;background:yellow;" class="hworld">
And:
myp.appendTo(jQuery('.hworld'));
Hope this helps...
There must be something else interfering with your code.
It works fine in this fiddle I created: http://jsfiddle.net/jasongennaro/7sGGq/