JQuery and frames - $(document).ready doesn't work - javascript

I have a page, with some code in js and jQuery and it works very well. But unfortunately, all my site is very very old, and uses frames. So when I loaded my page inside a frame, $(document).ready() doesn't fire up.
My frameset looks like:
<frameset rows="79,*" frameBorder="1" frameSpacing="1" bordercolor="#5996BF" noresize>
<frame name="header" src="Operations.aspx?main='Info.aspx'" marginwidth="0" marginheight="0" scrolling="no" noresize frameborder="0">
<frame name="main" src="Info.aspx" marginwidth="0" marginheight="0" scrolling="auto" noresize frameborder="0">
</frameset>
My page is loaded into the main frame. What should I do?

I have tried the method mentioned in another comment:
$("#frameName").ready(function() {
// Write you frame on load javascript code here
} );
and it did not work for me.
this did:
$("#frameName").load( function() {
//code goes here
} );
Even though the event does not fire as quickly - it waits until images and css have loaded also.

I know this is an old topic. But to help some of you who reach this page, here is my solution:
$($("#frameName")[0].contentWindow.document).ready(function() {
// Write you frame onready code here
});

I assume this is a similar problem I was having with DOMContentLoaded in an iframe.
I wrote a blog post about it.

If you want to fire the onload event for your frames, then follow these steps:
Assign an id and name to each <frame> tag. Make sure both id and name attributes value is same.
Use the following code to fire the onload event of the frame:
$("frameName").ready(function() {
// Write your frame onload code here
}

The following also worked for me:
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.js"></script>
<script>
$(window.parent.frames[0].document).ready(function() {
// Do stuff
});
</script>
The [0] indicates that it is the first frame in the document, [1] would be the second frame, and so on. This is particularly nice if you do not have control over the mark-up, and it is still utilizing document ready.

Have you tried to put the jQuery code inside the Info.aspx page?

Not sure what you're trying to do, but I have an even older classic asp app that operates out of frames, and I just recently added jQuery functionality and it is working great. The $(document).ready() works fine within a frame, but if you wish to reference the DOM in another frame, you'll have to use the Frame's onload event to let you know when the frame's DOM is loaded. Admittedly, I used iFrames, but the concept should be the same.

I have worked a long time with this post... here is my solution.
test.html
<!DOCTYPE HTML>
<html>
<head>
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script>
document.write('<frameset><frame name="frame_content" id="frame_content"></frame></frameset>');
$('#frame_content').attr('src', 'test2.html');
$('#frame_content').load(function()
{
if('${"#header"}' != '') {
$("#header", frame_content.document).remove();
}
});
if($('#frame_content').complete) $('#frame_content').trigger("load");
</script>
</head>
</html>
test2.html
<!DOCTYPE HTML>
<html>
<head>
</head>
<body>
<div id="header">You will never see me, cause I have been removed!</div>
</body>
</html>

I don't know if it is the best solution, but when I remove $(document).ready() and keep its body, everything works perfectly.

No need to modify the markup. Just fix the selector. It should be:
$("frame[name='main']").ready(function(){..});
not
$("#frameName").ready(function(){..});
Note: it seems the jQuery ready event fires multiple times. Make sure that is OK with your logic.

This answer may be late, but this reply may help someone like me...
This can be done via native Javascript code -
ifrm2 = var ifrm2 = document.getElementById('frm2');
if (ifrm2.contentDocument.readyState == 'complete') {
//here goes the code after frame fully loaded
}
//id = frm2 is the id of iframe in my page

There is no reason for $(document).ready() not to be called.
Be sure your page contains an include to jquery.js. Try to do a simple test with an empty HTML page and just an alert to see if there is another problem.
If you are trying to use this inside the HTML page that contains the frame's definition, keep in mind that there is no document there, you will have to use the

Related

Targeting an iframe with Js/jQuery BEFORE the DOM loads

In order to prevent an iframe from flashing, I'm setting its visibility inside a setTimeout (the CSS is set to visibility:hidden)
setTimeout(function(){
$n('#myFrame').css('visibility','visible');}, 750);
Works great, although when I load subsequent locations inside the frame, the flashing behavior returns since the visibility is already set.
What I'd like to do is create a function that targets the iframe BEFORE the DOM/page has loaded to set the visibility to hidden again and then setTimeout.
Keep in mind that this script will run on the ServiceNow platform, meaning some options are limited (can't load in document head, etc.)
It's sort of like a reverse document.ready(). Is this even possible?
Thanks for any leads,
Paco
Just set it in your source:
<iframe style="display: none;"></iframe>
Then un-hide it when you want to.
$('buttonToChangeTheIframePage').click(function(e){
e.preventDefault();
$('#myFrame').css('visibility','hidden');
$('#myFrame').delay(1000).css('visibility','visible');
});
This assumes you are loading locations from OUTSIDE the iframe - anything within the iframe (like a link) will still trigger this behaviour.
EDIT
This is actually better and will work for all circumstances (I think - just check no silly errors as not tested)
<iframe id="myFrame" src="http://www.google.com/" onLoad="hideUnhide();"></iframe>
function hideUnhide(){
$('#myFrame').css('visibility','hidden').delay(1000).css('visibility','visible');
}
Use addAfterPageLoadedEvent(func) in js_include_doc_type.js
<iframe id="gsft_main" style="visibility: hidden;">
anything ....
<script>
addAfterPageLoadedEvent(function() {
$j('#gsft_main').css('visibility','visible');
});
</script>
</iframe>

Chrome Javascript security?

So i have this empty page,
<html>
<head>
<title>JS</title>
<script type="text/javascript">
var container = document.getElementById("container");
console.log(container);
</script>
</head>
<body>
<div id="container"></div>
</body>
</html>
and for some reason console.log returns "null" instead of div object. But when i put code onto some website like jsfiddle, it works.
How do i fix this, is it a common problem?
JSFiddle may not mimic DOM loading correctly. The problem with your example is your JavaScript is executed before the DOM is completely loaded. The DOM is loaded top-down, so when your JavaScript is executed, the container div doesn't exist in the DOM yet.
You can move your script block after your div, that's a quick way to resolve the issue. Alternatively, you can listen for an event for when the DOM is loaded, then execute your code. This StackOverflow question demonstrates how to do that.

Accessing Elements Inside iframe and body Tags with JavaScript

I'm writing a GreaseMonkey script that modifies an attribute of an element with a specific ID, but I'm having some problems accessing it due to a nontraditional HTML hierarchy. Here's the relevant HTML:
<body>
...
<iframe id="iframeID">
<html>
...
<body id="bodyID" attribute="value">
...
</body>
...
</html>
</iframe>
...
</body>
Where attribute is the attribute that I'm attempting to modify.
At first, not realizing I was working with an iframe and a nested body tag, I tried this:
document.getElementById('bodyID').setAttribute("attribute","value")
While this worked fine in Firefox, Chrome tells me that I can't set the attribute of null, suggesting that it cannot find any elements with the id bodyID. How can I modify this attribute in a cross-browser friendly fashion?
You first need to pull the document of the <iframe>:
document.getElementById('iframeID').contentDocument
.getElementById('bodyID').setAttribute("attribute","value");
Live DEMO
BTW, if you want to get the <body> node, you don't need to give id or something like that, simply:
document.body
In your case, it's the document of the <iframe>:
document.getElementById('iframeID').contentDocument.body.setAttribute("attribute","value");
A lot simpler... Isn't it?
The best way, IMO, to do this is to listen for the load event fired by the iFrame, then look into the iFrame DOM as need. This guarantees that you'll have the iFrame DOM available when you need it and take a while shot.
$('#iframeID').on('load', function ()
{
alert('loaded'); // iFrame successfully loaded
var iFrameDoc = $('#iframeID')[0].contentDocument; // Get the iFrame document
$('body', iFrameDoc).attr('attribute', 'new value'); // Get the 'body' in the iFrame document and set 'attribute' to 'new value'
});

dom referencing only working correctly in IE

I have a javascript function that I am calling from an image onClick event in my page.
Basically the function sets a variable which is referencing an element within the same page.
here is how the function is called (note, the html is printed using PHP, but don't think that has any effect on the html itself):
echo "<img src='site/images/apps/show.gif' onClick='apps()' id='appbutton' style='#'>";
here is what the script references:
<iframe frameborder="0" name="app_frame" src="site/apps.html" width="0%" height="100%" scrolling="no"></iframe>
and finally, here is how it is referenced and what is done with it:
<script type="text/javascript">
function apps()
{
var element = document.getElementById("app_frame");
if (element.width == '0%')
{
parent.document.getElementById("frame").setAttribute("width","100%");
parent.document.getElementById("app_frame").setAttribute("width","0%");
parent.document.getElementById("appbutton").setAttribute("src","site/images/apps/show.gif");
parent.document.getElementById("wthrbutton").style.visibility="hidden";
}
else
{
parent.document.getElementById("frame").setAttribute("width","65%");
parent.document.getElementById("app_frame").setAttribute("width","35%");
parent.document.getElementById("appbutton").setAttribute("src","site/images/apps/hide.gif");
parent.document.getElementById("wthrbutton").style.visibility="visible";
}
}
</script>
The main issue is on the first line of the function, var element = document.getelementbyid.
Firefox, Chrome and Safari all hve issues with this, and none of them seem to set the variable, which renders the rest of the script useless, as the whole thing revolves around the variable.
Anyone know any other way of setting that element as a variable that would work in these browsers?
Thanks
That is because there is nothing with an id of app_frame. You have set the iframe's name to app_frame. Change your iframe's code to:
<iframe frameborder="0" name="app_frame" id="app_frame" src="site/apps.html" width="0%" height="100%" scrolling="no"></iframe>
An article pointing out this quirk in IE
MSDN's doc on getElementById states it returns names or id

How to add a click event to p elements in iframe (using jQuery)

How to add a click event to <p> elements in iframe (using jQuery)
<iframe frameborder="0" id="oframe" src="iframe.html" width="100%" name="oframe">
There's a special jQuery function that does that: .contents(). See the example for how it's works.
Your best best bet is to invoke the iframe AS LONG AS it's part of your domain.
iframe.html
<html>
<head>
<script>
window.MyMethod = function()
{
$('p').click();
}
</script>
</head>
<body></body>
</html>
And then use
document.getElementById('targetFrame').contentWindow.MyMethod();
To invoke that function.
another way is to access the iframe via window.frames.
<iframe name="myIframe" src="iframe.html"/>
and the javascript
child_frame = window.frames['myIframe'].document;
$('p',child_frame).click(function(){
alert('This click as bound via the parent frame')
});
That should work fine.
Wanted to add this, as a complete, copy-paste solution (works on Firefox and Chrome). Sometimes it is easy to miss to remember to call the event after the document, and so the iframe, is fully loaded:
$('#iframe').on('load', function() {
$('#iframe').contents().find('#div-in-iframe').click(function() {
// ...
});
});
The iframe must be on the same domain for this to work.
By giving a reference to the IFrame document as the second parameter to jQuery, which is the context:
jQuery("p", document.frames["oframe"].document).click(...);
To access any element from within an iframe, a simple JavaScript approach is as follows:
var iframe = document.getElementById("iframe");
var iframeDoc = iframe.contentDocument || iframe.contentWindow;
// Get HTML element
var iframeHtml = iframeDoc.getElementsByTagName("html")[0];
Now you can select any element using this html element
iframeHtml.getElementById("someElement");
Now, you can bind any event you want to this element. Hope this helps. Sorry for incorrect English.

Categories

Resources