Fri 22 Feb 2008
As pointed out by Jon’s blog post, simply use the dojo/dijit objects on the top window within an iframe won’t work for dojo APIs in most cases, because “the top level dojo object has no Out of the Box knowledge of the iframes or their content”.
Actually, dojo has two APIs in the core to support running code in the context of an iframe: dojo.withGlobal and dojo.withDoc. However, they do not have much attention, as most of their usage is only seen in the dijit.Editor code. Actually, they were introduced for the sole purpose of dojo.widget.Editor (which is the dojo 0.4 Editor widget) for dojo 0.4 in the first place.
Both of them have identical signature:
dojo.withGlobal(/*Object*/globalObject, /*Function*/callback,/*Object?*/thisObject, /*Array?*/cbArguments)
In order to use them, you can wrap your code in a function first, like this:
function iframefunc(){
dojo.byId(‘foo’);
dijit.byId(‘foo’);
dojo.query(‘a.foo’);
}
and call the function as this in an iframe:
dojo.withGlobal(window,iframefunc)
You can also call dojo APIs directly use dojo.withGlobal. Say you want to run dojo.byId(‘foo’) in an iframe, you can do:
dojo.withGlobal(window,'byId',dojo,['foo'])
Note that, the above code can also run correctly in the context of the top window.
The differences between dojo.withGlobal and dojo.withDoc is the first argument: if you want to only change document of a function call operates on, you can use dojo.withDoc instead and pass it with the document of an iframe.
RSS feed for comments on this post. TrackBack this post
February 22nd, 2008 at 6:25 pm
Interesting Cougar, thank you for pointing that out. I’ll have a look at them.
One other question is, does either of those allow you to operate a function like byId from the parent and have it parse for that id in all the iframes? Or do you have to implicitly specify the iframe you want to run the byId in. They are still very powerful functions, and I can see that it would be a breeze to have another function that wrapped the frame targeting withDoc in a loop of all the iframes and pass back an array of all the returns. I’m sure with more thought that could also be achieved with dojo.query. Those seem to be the two main areas of issue I’ve found with DOM targetting from the top level Dojo into iframes.
February 22nd, 2008 at 6:59 pm
Re JP:
You have to explicitly specify which iframe you want to run the code in. However, as you said, it is easy to write a wrapper function to go through all the frames in a page and collect the results, or just a dojo.map should do:
dojo.map(window.frames,function(f){
return dojo.withGlobal(f.contentWindow,…);
})
May 1st, 2008 at 12:23 pm
Hi liucougar. Congrats on everything good that has happened to you recently. Please send me an email, I want to discuss something with you.
Take care,
G
September 28th, 2008 at 8:25 am
Hey, Nice to know you
我也姓刘
而且也用Dojo
http://www.webwidgetwiki.com
November 2nd, 2009 at 5:50 am
Hi!
Thanks for a really good tip!
I am not able to make “dijit.byId” work, only “dojo.byId”! I have been trying different approaches, but can not make it work
I am trying to get holdt of a widget in the parent window, from within an iframe..
RenateWR