I have the following question:
I am trying to use a dwf viewer application, this is backuped by an activex that permits to view dwf files when the plugin is installed.
Usually one would use this plugin like this:
<object
classid = "clsid:A662DA7E-CCB7-4743-B71A-D817F6D575DF"
codebase = "http://www.autodesk.com/global/dwfviewer/installer/DwfViewerSetup.cab#version=6,0,0,200"
ID = "Eview"
width = "500"
height = "500"
border="0"></object>
then just call functions like this:
Eview.Viewer.ExecuteCommand("BLACKANDWHITE");
etc..
The thing is I am now creating the object in an Iframe by server side:
<iframe id="dwfFrame" name="dwfFrame" src="plot.aspx" width="100%" height="100%" onload="initDWF()"/>
in plot.aspx I write the dynamic dwf, and then when loading the iframe, the activex is opened and the dwf shown correctly.
// Now output the resulting DWF.
OutputReaderContent(Response, byteReader);
The problem is on my page I am unable to make Javascript calls cause I do not have a reference to the object, I tried issuing them to the Iframe but it doesn't work. Like this:
dwfViewer = document.dwfFrame;
dwfViewer.Viewer.ExecuteCommand("BLACKANDWHITE");
dwfViewer.ExecuteCommand("BLACKANDWHITE");
I beleive this is because the iframe is not the instancied activex object, is there anyway I could get ahold of this object so I can work on it?
Try:
var dwfFrameDoc = parent.dwfFrame.document;
var dwfViewer = dwfFrameDoc.getElementById('Eview');
I don't play around with multiple frames too often, but that is how you would address another frame. It shouldn't matter that the frame in question is an iframe. Each frame has its own window object. The document is a property of that object. parent refers to the parent of the current window or to itself if it is already the top level.
document.dwfFrame would get you the element whose id is dwfFrame, which is not the same as the window object of the iframe. Even if it were, doing dwfViewer.ExecuteCommand('BLACKANDWHITE'); would try to call ExecuteCommand as a method of the iframe's window, not the viewer object.
Related
If I have a document with for example 2 or more Iframes in each other, how can I access the main document's window object from the last one down the tree?
<html>
...
<iframe>
<iframe>
<!-- I'm here -->
</iframe>
</iframe>
...
I want to be able to redirect the browser window to another page but I cant seem to find a way to grab it's window object.
I tried something like
var outest = window;
if(outest.parent){
outest = outest.parent
}
But for some reason it appears that window has infinite parents. Any ideas?
top refers to the outmost window object, i.e. the browser window.
I use postMessage to send events from an iframe to it's parent document. I have control over both sides but the content comes from two different domains.
My simple problem is, that i can not identify the iFrame inside of it's parent callback method. The implementation looks like this:
In the iFrame:
parent.postMessage(JSON.stringify({action: "closeView" }),'*');
In the parent window:
window.addEventListener('message',function(event) {
if(event.origin !== 'https://example.com')
return;
// Parse message back to json
var messageObject = JSON.parse(event.data);
var source = event.source;
/* this is returning: Window -URL- */
console.log( source );
/* This will throw Permission denied, although this code is inside of "parent" */
console.log(source.parentNode);
},false);
I want to identify a certain parent element of the iframe, which is (logically) inside of the parent document.
When i try to use event.source.parentNode or some jQuery on said object, Firefox says, i can not do this to prevent XSS, error: Error: Permission denied to access property 'parentNode'
How can i get the parent element of the iFrame, that triggered the postMessage event listener?
you can use window names for this, as they pass from iframe tag to iframe context.
parent doc:
<iframe name=fr2 src="data:text/html,%3Chtml%3E%0A%20%3Cscript%3E%20parent.postMessage%28%7Bname%3A%20window.name%7D%2C%20%22*%22%29%3B%3C/script%3E%0A%3C/html%3E"></iframe>
<iframe name=fr3 src="data:text/html,%3Chtml%3E%0A%20%3Cscript%3E%20parent.postMessage%28%7Bname%3A%20name%7D%2C%20%22*%22%29%3B%3C/script%3E%0A%3C/html%3E"></iframe>
<script>onmessage = function(e){ // use real event handlers in production
alert("from frame: " + e.data.name);
};</script>
iframe doc:
<html>
<script> parent.postMessage({name: name}, "*");</script>
</html>
which alerts "fr2", then "fr3".
you can then easily use the name attrib to find the iframe in the parent DOM using attrib CSS selectors.
illustrative demo of window.name+iframe concept: http://pagedemos.com/namingframes/
this painfully simple approach is also immune to issues arising from same-url iframes.
As per my understanding this may be try
here suppose your main window's url is www.abc.com\home.php
<body>
<iframe src="www.abc.com\getOtherDomainContent.php?otherUrl=www.xyz.com"/>
</body>
getOtherDomainContent.php in this file need to write ajax call which get cross url content and push that content in current iframe window(getOtherDomainContent.php)'s body part.
getOtherDomainContent.php
Code:
<html>
<head>
//import jqry lib or other you use.
<script>
$(document).ready({
//getcontent of xyz.com
var otherUrlContent=getAjaxHtml("www.xyz.com");
$("body").html(otherUrlContent);
// further code after content pushed.
//you can easily access "parent.document" and else using parent which will give you all thing you want to do with your main window
});
</script>
</head>
</html>
Like seen in this thread: postMessage Source IFrame it is possible to compare each iframes contentWindow with event.source like this:
/*each(iframe...){ */
frames[i].contentWindow === event.source
But i did not like this too much. My solution for now looks like this:
In the iFrame:
parent.postMessage(JSON.stringify({action: "closeView", viewUrl: document.URL}),'*');
Update:
docuent.URL can become a problem, when you use queries or links with location (#anchor) since your current url will become different from the one of the iframe source. So Instead of document.URL it's better to use [location.protocol, '//', location.host, location.pathname].join('') (Is there any method to get the URL without query string?)
In the parent document:
window.addEventListener('message',function(event) {
if(event.origin !== 'https://example.com')
return;
// Parse message back to json
var messageObject = JSON.parse(event.data);
// Get event triggering iFrame
var triggerFrame = $('iframe[src="'+messageObject.viewUrl+'"]');
},false);
Each event will have to send the current iFrame URL to the parent document. We now can scan our documents for the iFrame with the given URL and work with it.
If some of you know a better way please post your answers.
I'm having trouble accessing the DOM of an iframe content document if I create the iframe dynamically in JavaScript rather than hard-coding it in the HTML.
I'm finding this so far testing in Mac FF26 and Safari 6. It is a local iframe document on the desktop, so there should be no cross-domain issues.
The iframe I generate appears normally in the browser window. But trying to access it with contentDocument, the body element seems to be empty.
Is this a known issue? Perhaps I'm generating my iframe in an unusual way:
var newIframe = document.createElement("iframe");
newIframe.id = "generatedIframe";
newIframe.src = "test.html";
document.body.appendChild(newIframe);
var iframeTag = document.getElementById("generatedIframe");
// the iframe will be appearing normally in the browser now
// but this fails -- innerHTML is empty string:
var iframeContent = iframeTag.contentDocument.getElementsByTagName("body")[0].innerHTML;
// same reference code works if the iframe is hard-coded in HTML instead
In fact your problem is not the way you generated your iframe.
The iframe DOM is only available after it has been loaded.
The code behind illustrates what I mean :
In your parent window container :
<script>
function doSomething() { alert(iframeTag.contentDocument.getElementsByTagName("body")[0].innerHTML()); }
</script>
In your iframe document
<body onload="window.parent.doSomething();"></body>
I have checked all the reload iframe from another iframe posts on stackoverflow...and I have tried all their solutions but it doesn't seem to help me! So my problem is that I have two iframes on the same page. The iframe's sources are php files that interact with each other, however I need the iframes to reload that way the changes are shown. I have tried many different ways (which I will list below). These iframes are from the same domain. Maybe it is something else that is messing this up? Thanks in advance.
Different statements called from inside one iframe:
parent.document.getElementById(id).src = parent.document.getElementById(id).src;
parent.getElementById(id).location.reload();
Trying to call a parent function that works in the parent window:
Inside iframe -
parent.refresh(id);
Parent window working function -
function refresh(id) {
document.getElementById(id).src = document.getElementById(id).src;
}
If you assign name to iframe most browsers will let you access the iframe's window object via the name value. This is different from referring to an iframe by its id property which will give you a reference to the iframe element itself (from its owner document), and not the iframe's content window.
Simple Example: (from the parent document)
<iframe name='iframe1Name' id='iframe1Id'></iframe>
<script>
// option 1: get a reference to the iframe element:
var iframeElem = document.getElementById('iframe1Id');
// update the element's src:
iframeElem.src = "page.html";
// option 2: get a reference to the iframe's window object:
var iframeWindow = window.iframe1Name;
// update the iframe's location:
iframeWindow.location.href = "page.html";
</script>
Let's review your code:
parent.document.getElementById(id).src = parent.document.getElementById(id).src;
This works if executed from within the iframe, provided you use the correct id. You may want to use a debugger to verify that parent.document.getElementById(id) returns a reference to the correct element, and check your console to see if any exceptions are being thrown (try hitting F12). Since you didn't post your full code (including markup) there's no way I can to think of to tell what the issue is here.
Debugging tips:
check parent.location.href to make sure you are accessing the window you think you are,
check parent.document.getElementId(id) to make sure that you get an element object (as opposed to null or undefined),
check parent.document.getElementById(id).tagName to make sure you are using the correct ID (tagName should === "IFRAME")
This line:
parent.getElementById(id).location.reload();
has two problems:
getElementById() is a function of document, but it is being called from parent which is a window object, and
location is a property of a window object. You are trying to access the iframe element's location property, which does not exist. You need a reference to the iframe's window, not its element.
Besides the name method, there are other ways to get the iframe's window object:
document.getElementById('iframeId').contentWindow; // for supported browsers
window.frames["iframeName"]; // assumes name property was set on the iframe
window.frames[i]; // where i is the ordinal for the frame
If changing the src of the iframe element is not working for you, these other fixes might:
parent.document.getElementById(id).contentWindow.location.reload();
or
parent.frames["yourIframeName"].location.reload(); // requires iframe name attribute
or
parent.frames[0].location.reload(); // frames of immediate parent window
or
top.frames[0].location.reload(); // frames of top-most parent window
Caution: If using the name method be careful not to use a common value for name, like "home", for example, as it conflicts with a FireFox function called home() and so Firefox will not automatically create a reference to an iframe's window if it is named home. The most reliable method is probably to use window.frames[] as I believe that has been around for a long time (works in FF / Chrome / Safari / IE6+ (at least))
A more in-depth (but pretty minimal) example follows, tested in Chrome, FF, and IE:
File #1: frametest.html (the parent window)
<!DOCTYPE html>
<html>
<body>
<iframe id="frame1Id" name="frame1Name" src="frame1.html"></iframe>
<iframe id="frame2Id" name="frame2Name" src="frame2.html"></iframe>
</body>
</html>
File #2: frame1.html (frame 1's src)
<!DOCTYPE html>
<html>
<body>
FRAME 1
<script>
document.body.style.backgroundColor="#ccc";
setTimeout(function(){document.body.style.backgroundColor="#fff";},100);
document.write(new Date());
</script>
<input type="button" onclick="parent.document.getElementById('frame2Id').src=parent.document.getElementById('frame2Id').src;" value="Refresh frame 2 by ID"/>
<input type="button" onclick="parent.frame2Name.location.reload();" value="Refresh frame 2 by Name"/>
</body>
</html>
File #3: frame2.html (frame 2's src)
<!DOCTYPE html>
<html>
<body>
FRAME 1
<script>
document.body.style.backgroundColor="#ccc";
setTimeout(function(){document.body.style.backgroundColor="#fff";},100);
document.write(new Date());
</script>
<input type="button" onclick="parent.document.getElementById('frame1Id').src=parent.document.getElementById('frame1Id').src;" value="Refresh frame 2 by ID"/>
<input type="button" onclick="parent.frame1Name.location.reload();" value="Refresh frame 2 by Name"/>
</body>
</html>
This example demonstrates how to define and manipulate iframes by id and by name, and how to affect one iframe from within a different iframe. Depending on browser settings, origin policy may apply, but you already said that your content was all from the same domain so you should be OK there.
I'm attempting to convert a Greasemonky script to an extension for Firefox and I'm trying to make my extension automatically attach a simple script to any webpage when a new tab is opened. I'm converting the script from Greasemonkey because I'd like to take advantage of advanced preferences and menu options.
I access the tab using this:
var container = gBrowser.tabContainer;
container.addEventListener("TabOpen", tabAdded, false);
function tabAdded(event) {
var newtabwindow = event.target.____ //I don't know what goes here
//attach script to newtabwindow
}
and my goal is to append the script to the document in the new tab once it loads using this function:
function scriptrunner(targetwindow) {
var myScript = targetwindow.content.document.createElement('script');
myScript.type = 'text/javascript';
myScript.setAttribute('src','chrome://addonname/content/addonscript.js');
targetwindow.content.document.getElementsByTagName('head')[0].appendChild(myScript);
}
This function works fine to attach the script to the current page when attached to a toolbar button with oncommand="scriptrunner(window)", but I don't know how I could access the window in the newly opened tab, or if I should cut out the window from the equation and access the document another way.
You are looking for contentWindow, which is a property of the browser element.
Given a tab, call gBrowser.getBrowserForTab to acquire the browser element associated with the tab. Then access either contentDocument or contentWindow property of the browser element (these are equivalent to the document and window objects you should already be familiar with).
Also -- if I'm not mistaken -- you'll need to listen for the "load" event of the contentWindow in addition to listening to events for the tab.