I have a web page that uses a frameset.
Due to scripting and object dependencies, I need to load the frames in a specific order.
I have used this example as a template:
The JavaScript Source: Navigation: Frames Load Order
This loads an empty page in place of the page I need to load last, then replaces it with the correct page after the first page has loaded.
However: I also need to use the browser Back button. If you run the sample at the above link, let both frames load, then click the Back button, the top frame reverts to the temporary blank page. It is then necessary to click the Back button again to navigate to the page before the frameset.
Is there a way to force frames to load in a specific order without this Back button behavior - or a way to force the Back button to skip the empty page?
This needs to work with Internet Explorer 6 and 7 and preferably with Firefox 3 as well.
You mention this quite a lot in this post...
This is a legacy system. The frameset is required.
If you are working on a legacy system, then I think it is time you accepted how framesets behave in terms of the browser's back button. If it is truly a legacy system, you don't need to fix this behaviour. If it is actually NOT a legacy system and you need to fix this problem, you need to get away from using a frameset. Framesets were deprecated from the HTML standards and shouldn't be used.
Why not use three iframes in the desired order, then resize/move them to the appropriate places?
<iframe id="a1" src="page-to-load-first.htm"></iframe>
<iframe id="a2" src="page-to-load-second.htm"></iframe>
<iframe id="a3" src="page-to-load-third.htm"></iframe>
<script>
function pos(elem,x,y,w,h) {
if (!elem.style) elem=document.getElementById(elem);
elem.style.position='absolute';
elem.style.top = y+'px';
elem.style.left= x+'px';
elem.style.width=w+'px';
elem.style.height=h+'px';
}
window.onload = function() {
window.onresize=function() {
var w = window.innerWidth || document.documentElement.clientWidth;
var h = window.innerHeight || document.documentElement.clientHeight;
var w3 = w/3;
var h2 = h/2;
pos('a1',0,0,w3,h); /* left 1/3rd */
pos('a2',w3,0,w3+w3,h2);
pos('a3',w3,h2,w3+w3,h2);
};
window.onresize();
};
</script>
Build the frames themselves using JavaScript:
<html>
<head>
<script>
function makeFrame(frameName) {
var newFrame = document.createElement('frame');
newFrame.id=frameName;
if(frameName=="B") {
newFrame.onload=function() {makeFrame("C")};
newFrame.src = 'http://www.google.com';
}
else {
newFrame.src = 'http://www.yahoo.com';
}
document.getElementById('A').appendChild(newFrame);
}
</script>
</head>
<frameset name='A' id='A' rows="80, *" onload="makeFrame('B')"></frameset>
</html>
Related
Is it possible to change styles of a div that resides inside an iframe on the page using CSS only?
You need JavaScript. It is the same as doing it in the parent page, except you must prefix your JavaScript command with the name of the iframe.
Remember, the same origin policy applies, so you can only do this to an iframe element which is coming from your own server.
I use the Prototype framework to make it easier:
frame1.$('mydiv').style.border = '1px solid #000000'
or
frame1.$('mydiv').addClassName('withborder')
In short no.
You can not apply CSS to HTML that is loaded in an iframe, unless you have control over the page loaded in the iframe due to cross-domain resource restrictions.
Yes. Take a look at this other thread for details:
How to apply CSS to iframe?
const cssLink = document.createElement("link");
cssLink.href = "style.css";
cssLink.rel = "stylesheet";
cssLink.type = "text/css";
frames['frame1'].contentWindow.document.body.appendChild(cssLink);
// ^frame1 is the #id of the iframe: <iframe id="frame1">
You can retrieve the contents of an iframe first and then use jQuery selectors against them as usual.
$("#iframe-id").contents().find("img").attr("style","width:100%;height:100%")
$("#iframe-id").contents().find("img").addClass("fancy-zoom")
$("#iframe-id").contents().find("img").onclick(function(){ zoomit($(this)); });
Good Luck!
The quick answer is: No, sorry.
It's not possible using just CSS. You basically need to have control over the iframe content in order to style it. There are methods using javascript or your web language of choice (which I've read a little about, but am not to familiar with myself) to insert some needed styles dynamically, but you would need direct control over the iframe content, which it sounds like you do not have.
Use Jquery and wait till the source is loaded,
This is how I have achieved(Used angular interval, you can use javascript setInterval method):
var addCssToIframe = function() {
if ($('#myIframe').contents().find("head") != undefined) {
$('#myIframe')
.contents()
.find("head")
.append(
'<link rel="stylesheet" href="app/css/iframe.css" type="text/css" />');
$interval.cancel(addCssInterval);
}
};
var addCssInterval = $interval(addCssToIframe, 500, 0, false);
Combining the different solutions, this is what worked for me.
$(document).ready(function () {
$('iframe').on('load', function() {
$("iframe").contents().find("#back-link").css("display", "none");
});
});
Apparently it can be done via jQuery:
$('iframe').load( function() {
$('iframe').contents().find("head")
.append($("<style type='text/css'> .my-class{display:none;} </style>"));
});
https://stackoverflow.com/a/13959836/1625795
probably not the way you are thinking. the iframe would have to <link> in the css file too. AND you can't do it even with javascript if it's on a different domain.
Not possible from client side . A javascript error will be raised "Error: Permission denied to access property "document"" since the Iframe is not part of your domaine.
The only solution is to fetch the page from the server side code and change the needed CSS.
A sort of hack-ish way of doing things is like Eugene said. I ended up following his code and linking to my custom Css for the page. The problem for me was that, With a twitter timeline you have to do some sidestepping of twitter to override their code a smidgen. Now we have a rolling timeline with our css to it, I.E. Larger font, proper line height and making the scrollbar hidden for heights larger than their limits.
var c = document.createElement('link');
setTimeout(frames[0].document.body.appendChild(c),500); // Mileage varies by connection. Bump 500 a bit higher if necessary
Just add this and all works well:
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
If the iframe comes from another server, you will have CORS ERRORS like:
Uncaught DOMException: Blocked a frame with origin "https://your-site.com" from accessing a cross-origin frame.
Only in the case you have control of both pages, you can use https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage to safely send messages like this:
On you main site(one that loads the iframe):
const iframe = document.querySelector('#frame-id');
iframe.contentWindow.postMessage(/*any variable or object here*/, 'https://iframe-site.example.com');
on the iframe site:
// Called sometime after postMessage is called
window.addEventListener("message", (event) => {
// Do we trust the sender of this message?
if (event.origin !== "http://your-main-site.com")
return;
...
...
});
Yes, it's possible although cumbersome. You would need to print/echo the HTML of the page into the body of your page then apply a CSS rule change function. Using the same examples given above, you would essentially be using a parsing method of finding the divs in the page, and then applying the CSS to it and then reprinting/echoing it out to the end user. I don't need this so I don't want to code that function into every item in the CSS of another webpage just to aphtply.
References:
Printing content of IFRAME
Accessing and printing HTML source code using PHP or JavaScript
http://www.w3schools.com/js/js_htmldom_html.asp
http://www.w3schools.com/js/js_htmldom_css.asp
So here is what I'm doing so far:
<script>
var win;
function OpenInNewTab(url )
{
// var win;
if (win)
{
win.close();
}
win =window.open(url, 'myWin');
win.focus();
}
</script>
And then my links are phrased like this (in order to take advantage of the Javascript function):
<li>Anti-Aging Firewalls</li>
The issue is, that this solution cannot be scaled upwards for all the URLs on my page. Which means that I have to call onclick for each and every URL that I want to behave this way. Is there an elegant way to scale this solution so that I don't have to keep on typing in "onclick" for each link? (or at least reduce the effort it takes to keep on typing this in?)
Just make those links have a normal href value (i.e. the URL the link will point to) and give them a rel attribute value of external to indicate you want them open in a new tab. Then just have a small JavaScript snippet search for this attribute value and then change it so the link opens in a new tab.
This is nice because the link still works even if JavaScript is disabled or otherwise fails.
<li>Anti-Aging Firewalls</li>
<script>
function externalLinks() {
if (!document.getElementsByTagName) return;
var anchors = document.getElementsByTagName("a");
for (var i=0; i<anchors.length; i++) {
var anchor = anchors[i];
if (anchor.getAttribute("href") &&
anchor.getAttribute("rel") == "external")
anchor.target = "_blank";
}
}
window.onload = externalLinks;
</script>
This article is old but explains it quite well. It can also be simplified if you use a framework like jQuery.
Add target="_blank" to your anchors is the simplest way.
anchor
If you don't want to modify every anchor element within the page (which is dirty work), you could add a <base> element in <head>:
<base target="_blank">
Alternatively you could use JavaScript to add that attribute in bulk on DOM ready:
var anchors = document.getElementsByTagName('a');
for (var i = 0; i < anchors.length; i++) {
anchors[i].target = "_blank";
}
why are you not using target attribute here ?
a href="some like here" target="_blank">Google
"Which can be reused," yes, absolutely.
Use the target attribute but rather than setting it to _blank, give it a name.
The following markup will open up the link into a new empty tab, so clicking three links will open three tabs:
click here
But the following markup will open up the link into a single specified tab, which it will be reused when subsequent links are followed:
click here
Set target to any name you want and all links to that target will predictably open in the same tab. If no tab yet exists with that name a new one will be opened.
This feature has been around since Netscape introduced frames. Today most people only use it with _self or _blank as the target, but using named targets is still as valid as ever.
I have an MVC grid which is rendered in by a json call on page load.
On clicking any tag of Grid I need to refresh this grid.
So I wrote this javascript.
$("#SearchGrid a").live("click", function (event) {
var link = event.currentTarget.attributes[0].childNodes[0].wholeText;
$("#SearchGrid").load(link);
return (false);
});
Its working fine with IE9 and other browsers. But I need to make it workable on IE8.
In IE8 its not loading the grid in same div, instead it redirects it to a new page, containing just the grid which is return from json call.
Try this. It uses the attribute href directly instead of your IE proprietary code
$("#SearchGrid a").live("click", function () {
var link = $(this).attr('href');
$('#SearchGrid').load(link);
return false;
}
not sure what the problem might be, but here are some tips on debugging it:
- var link = 'some-page.html'
try to see if you code actually returns any html data in IE8 - if it does then the problem lies in var link = event.currentTarget.attributes[0].childNodes[0].wholeText;
- instead of load(), try to use an $.ajax call or a json call and see waht happens.
I hope these will prove useful
I am launching a mobile site and I want it to have a loading icon while loading all the content and images.
Details:
I have several pages. I want when I click on it will load the pages (to other html page), but I don't want to show the page without fully loaded and I want to show loading animation while it loading all the content. Once, the content is fully loaded. then the loading animation have to hide.
How to do that?
You can make a large <div> at the beginning of the page, then hide it using Javascript in the load event or using an illegal <style> block at the end of the <body>.
You need to give a more specific question to get more specific (useful answers).
In the meantime here are some (hopefully useful) resources:
http://www.devcurry.com/2009/05/display-progress-bar-while-loading.html
http://jquery-howto.blogspot.com/2009/04/display-loading-gif-image-while-loading.html
http://banagale.com/display-a-simple-loading-message-and-animated-loading-gif-using-javascript.htm
http://yensdesign.com/2008/11/how-to-create-a-stylish-loading-bar-as-gmail-in-javascript/
This one may come particularly if it applies to your situation:
Showing a div while page is loading, hiding when its done
Good luck!
Any number of ways, but you will need javascript.
You are ready when all image assets have been loaded. Define full screen div that covers the whole page. In this div, show e.g. loading spinner animated gif and what ever text you want.
<html>
<head> .. </head>
<body>
<div id="loader"> .. </div>
<div id="content" style="display:none"> .. </div>
<script> .. </script>
</body>
</html>
On your script preload all images. This ensures that they are in cache when they are needed.
<script>
var loadc = 0;
function _preload(path) {
var image = new Image;
image.src = path;
image.addEventListener('load', function() {
loadc++;
if (loadc == images.count) {
$("#loader").hide();
$("#hide").show();
}
// update here progress counter on loading div
};
}
var images = [ '/image/some.png', '/foo/bar.png' ]
$(document).ready(function() {
for (var i = 0 ; i < images.length; i++) _preload(images[i]);
});
</script>
You need to define in images array all assets that you want to be ready when content div is shown, this includes stuff referred from CSS and DOM and possible dynamic DOM. You can use this same method for other assets, like audio and json.
I have an application that I would like to embed inside our companies CMS. The only way to do that (I am told), is to load it in an <iframe>.
Easy: just set height and width to 100%! Except, it doesn't work.
I did find out about setting frameborder to 0, so it at least looks like part of the site, but I'd prefer not to have an ugly scrollbar inside a page that allready has one.
Do you know of any tricks to do this?
EDIT: I think I need to clarify my question somewhat:
the company CMS displays the fluff and stuff for our whole website
most pages created through the CMS
my application isn't, but they will let me embedd it in an <iframe>
I have no control over the iframe, so any solution must work from the referenced page (according to the src attribute of the iframe tag)
the CMS displays a footer, so setting the height to 1 million pixels is not a good idea
Can I access the parent pages DOM from the referenced page? This might help, but I can see some people might not want this to be possible...
This technique seems to work (gleaned from several sources, but inspired by the link from the accepted answer:
In parent document:
<iframe id="MyIFRAME" name="MyIFRAME"
src="http://localhost/child.html"
scrolling="auto" width="100%" frameborder="0">
no iframes supported...
</iframe>
In child:
<!-- ... -->
<body>
<script type="text/javascript">
function resizeIframe() {
var docHeight;
if (typeof document.height != 'undefined') {
docHeight = document.height;
}
else if (document.compatMode && document.compatMode != 'BackCompat') {
docHeight = document.documentElement.scrollHeight;
}
else if (document.body
&& typeof document.body.scrollHeight != 'undefined') {
docHeight = document.body.scrollHeight;
}
// magic number: suppress generation of scrollbars...
docHeight += 20;
parent.document.getElementById('MyIFRAME').style.height = docHeight + "px";
}
parent.document.getElementById('MyIFRAME').onload = resizeIframe;
parent.window.onresize = resizeIframe;
</script>
</body>
BTW: This will only work if parent and child are in the same domain due to a restriction in JavaScript for security reasons...
You could either just use a scripting language to include the page into the parent page, other wise, you might want to try one of these javascript methods:
http://brondsema.net/blog/index.php/2007/06/06/100_height_iframe
http://www.experts-exchange.com/Web_Development/Web_Languages-Standards/PHP/Q_22840093.html
Provided that your iframe is hosted on the same server as the containing page, you can access it via javascript.
There are a number of suggested methods for setting the iframe to the full height of the contents, each with varying degrees of success - a google for this problem shows that it's quite a common one, with no real, one-size-fits-all consensus solution i'm afraid!
Several people have reported that this script does the trick, but may need some modification for your specific case (again, assuming your iframe and parent page are on the same domain).
I might be missing something here, but adding scrolling=no as an attribute to the iframe tag normally gets rid of the scrollbars.