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
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.
<div data-role="page" id="samples">
<div data-role="header" data-position="fixed">Back<h1>Ceremony Planner 2.0 - Samples</h1></div>
<object type="text/html" data="http://www.thereverendmichael.com/ceremony-samples"></object>
</div>
The object scrolls and works fine on all browsers but will not scroll on mobile, it gets cut off and bottom-clipped. Can anyone tell me how I can fix this?
Try this:
First: Make you sure that you put the viewport inside <head> like
<head><meta name=viewport content="width=device-width, initial-scale=1"></head>
Use <iframe> instead <object>
Add a wrapper to the <iframe>and add the following style
html
<div class="wrap">
<iframe src="http://www.thereverendmichael.com/ceremony-samples"></iframe>
</div>
css
.wrap {
// -webkit-overflow-scrolling: touch; Non-standard!
overflow-y: scroll;
}
SOURCE: https://www.w3schools.com/cssref/css3_pr_overflow-y.asp
If it doesn't work uncomment the other style although I see the documentation and is not recommended to use it see here.
However here is working: https://www.w3schools.com/tags/tryit.asp?filename=tryhtml_iframe you can see
the style that applies to #iframewrapper watching the view-source (ctrl+u in your browser) and looking for #iframewrapper
Hope this helped you!
I have a requirement to create a please wait page using jQuery 1.6.2 for an existing jsp page. I was able to get the div overlay to work, along with an please wait animation in a modal window in the center of the page. However, the overlay only covers one of the framesets, the center one.
The html structure is basically (I'm leaving a lot out for clarity):
...
<frameset >
<frame id="topMostFrame">
<frameset>
<frame id="leftMostframe">
<frame id="centerMostFrame">
</frameset>
</frameset>
<noframes>
</noframes>
</body>
</html>
JQUERY
function getTheOverlay(){
$(document).ready(function() {
$("#loading-div-background").css({opacity: 0.5});
$("#loading-div-background").show();
//alert("In getOverlay!");
});
}
function remove(){
$(document).ready(function() {
$('#loading-div-background').hide();
});
}
HTML
<div id="loading-div-background" style="display:none" class="ui-widget">
<div id="loading-div" class="ui-corner-all">
<img style="height:80px;margin:50px;" src="/images/loading.gif" alt="Loading.."/>
</div>
</div>
CSS
#loading-div-background {
display:none;
position:absolute;
top:0;
left:0;
background:gray;
width:100%;
height:100%;
/* Next 2 lines IE8 */
-ms-filter: "progid:DXImageTransform.Microsoft.Alpha(Opacity=70)";
filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=70);
}
#loading-div {
width: 300px;
height: 200px;
background-color: #ffffff;
text-align:center;
position:absolute;
left: 50%;
top: 50%;
margin-left:-150px;
margin-top: -100px;
}
I tried moving the html to load in my jquery function, but it didn't display the overlay in IE8. I also had a time getting IE8 to work with the overlay itself, but that is fixed using the CSS above.
I need to disable the links on the left frame, which is probably the approach I'll use or else cover them with the overlay. Yes I know frames are bad, but that is what I was given to work with.
I can't get the overlay to go over the other framesets and cover the entire page. I've read that this is impossible to do with framesets, although I'm guessing there could be a workaround. However, when I use an alert for debugging purposes, the overlay covers over the entire page.
My question is: why is using an alert making the overlay cover everything? Is there something else I could do to get the same effect, even with the framesets?
I faced this same problem and this is what I found that worked for me.
A frame is basically a window object. All the rules about windows apply to frames. A div belongs to a document which is held inside a window. Since the document can't leave its window, the div can't leave its window. You're asking for control at the level of the browser, but all you are permitted is control at the level of the document.
However, you may do a DIV over an iframe but not a frameset.
UPDATE:
Take this example my friend, It took some time for me to solve it, but really , StackOverflow has helped me a lot, so I feel that I must put this example here to help others.
This the html of page-container, it contains an iframe that will request the page-frameset that you are wanting to overlay.
<head>
<style type="text/css">
html, body#mybcontainer_body{margin:0px;padding:0px;border:none;height:100%;width:100%;}
#mybcontainer_div{position:absolute;top:0px;bottom:0px;left:0px;right:0px;}
#mybcontainer_iframe{position:absolute;top:0%;left:0%;height:100%;width:100%;}
</style>
</head>
<body id="mybcontainer_body" >
<div id="mybcontainer_dialog" style="display:none;">Some Text Here</div>
<div id="mybcontainer_div"><iframe id="mybcontainer_iframe" border="0" frameborder="0" scrolling="no" noresize="noresize" src="page-two-contain-frameset"></iframe></div>
</body>
My Regards
I ended up using show/hide over the frameset after the explaination from Cairo Solutions. That did work, but I don't believe it's possible to cover multiple framesets with one div.
This is the code I used:
$('#divName a',top.frames['leftframe'].document).show();
$('#divName a',top.frames['leftframe'].document).hide();
Then I just used the div I created as an overlay in the main frameset to work in conjunction with this and that solved the problem.
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).
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>