Jump to content

How to Pass events between iframes and functions?


mEno

Recommended Posts

Hello,I have a main html page which creates an iframe, something like: <iframe id='somefrm' src="http://somepage/frm.html" title="My frame" name='somefrm' frameborder="0" border="0" cellspacing="0" style="border-style: none;width: 34%;">text</iframe>Now, the above iframe has for example this in it:<body><a href="http://msn.com">First link inside my frm.html</a><br /><a href="http://msn.ca">Second link inside my frm.html</a><br /></body>I want to add an event to the links from this iframe from my main page like this:window.frames[0].document.getElementsByTagName('a')[0].onmousemove=Functi;window.frames[0] refers to the first frame (assuming that's the above). In the above line I am assigning the first anchor in the iframe the onmousemove attribute and tell it to execute the function Functi when a user moves the mouse over that link in the iframe.This works almost well. The function is called but the problem is that I need to operate on the event that's generated and hence need a reference to it. The function Functi looks something like: and it is declared in the main html page:function Functi(e) { if (!e) var e = window.event; // operate on e}Now, the problem is how can I correctly pass the 'event' that happened in the iframe to the function Functi? I am sure that the problem lies somewhere with the iframes because assigning exactly in this same way the onmousemove attribute to a link in my main page works perfectly fine. So, this works well:document.getElementsByTagName("a")[1].onmouseover=Functi;The above will give the onmouseover property to the second anchor in my main page, and when I hover over it, it calls the function and accesses the 'event' without problems.I tried doing something like:window.frames[0].document.getElementsByTagName('a')[0].onmousemove=function(){Functi(event);};But it doesn't help. The error I get when I hover over the link in my iframe is: "Object expected" on the line that tries to access the event in the function Functi.Thanks in advance for your replies.

Link to comment
Share on other sites

<body><a onmouseover="call_func('msn1')" href="http://msn.com">First link inside my frm.html</a><br /><a onmouseover="call_func('msn2')" href="http://msn.ca">Second link inside my frm.html</a><br /></body>function call_func(what) { if (what == "msn1") { // do that };else if (what == "msn2") { // do that 2 }}

Could this help?

Link to comment
Share on other sites

That sounds like an Explorer error, so I'm guessing you're in Explorer. If so, you're getting the event from window.event. Think about what that might refer to. Probably an event object that exists in the same space where Functi is defined. But that is not the event you want to capture, which is why the event object seems not to exist. The event that you want takes place in your iFrame, which an entirely different space. (iFrames are essentially windows.) See if you can get a reference to to the event property of the iFrame.I've never done that, so I'm just guessing. But that's where I'd look first.

Link to comment
Share on other sites

I got the sense that Functi is in fact being executed, but that Functi cannot get a reference to the event object. I believe the original definition should work because Functi looks like it is being embedded in the function as a closure.This can be tested by putting a temporary alert statement at the top of Functi. I would do this before making dsonesuk's suggested change. If you get the alert, the reference works. If not, try dsonesuk's suggestion.On a related topic, it's worth remembering that IE often identifies line numbers incorrectly, especially if some lines are commented out.

Link to comment
Share on other sites

Thanks for the answers.

<body><a onmouseover="call_func('msn1')" href="http://msn.com">First link inside my frm.html</a><br /><a onmouseover="call_func('msn2')" href="http://msn.ca">Second link inside my frm.html</a><br /></body>function call_func(what) { if (what == "msn1") { // do that };else if (what == "msn2") { // do that 2 }}

Could this help?

This does not help because I don't want to (let's assume I cannot) modify the iframe content. That is why I am trying to just go through the list of links from my main page and pick the correct one and then give it additional attributes.
That sounds like an Explorer error, so I'm guessing you're in Explorer. If so, you're getting the event from window.event. Think about what that might refer to. Probably an event object that exists in the same space where Functi is defined. But that is not the event you want to capture, which is why the event object seems not to exist. The event that you want takes place in your iFrame, which an entirely different space. (iFrames are essentially windows.) See if you can get a reference to to the event property of the iFrame.I've never done that, so I'm just guessing. But that's where I'd look first.
I am using Internet Explorer to check because that's only browser that at least reports errors when I have them in the JS/HTML code. I think as well that this is the problem, that the event is generated but it is the iframe window that catches it and hence the function in the main window doesn't see it. That is why I asked if anyone knows how to get the reference to this iframe window event so that I can pass it to the function in the main window. I have tried numerous variations but none seem to work.
you need to add 'parent.' to the start of the function to tell it to look in the parent page which will be the mainpage. Trywindow.frames[0].document.getElementsByTagName('a')[0].onmousemove=function(){parent.Functi(event);};
Just tried, and it still doesn't work. I get exactly the same problem/error. I am not sure how function(){parent.Functi(event);}; is passed or what is its scope in regards to the iframe. I mean, I do all my modifications on one html page in which I have JS code which declares the function Functi in the <head> and then in the <body> I declare an iframe. Now, theoretically it should work and it's logical that the onmousemove effect is exectued in the iframe which is a child of the main page. But, the iframe's parent is <body> and the function is in <head>. Is it still valid then to use parent? Or do I need parent.parent.head? (The .head is just English, that's not the exact syntax).
Link to comment
Share on other sites

I got the sense that Functi is in fact being executed, but that Functi cannot get a reference to the event object. I believe the original definition should work because Functi looks like it is being embedded in the function as a closure.This can be tested by putting a temporary alert statement at the top of Functi. I would do this before making dsonesuk's suggested change. If you get the alert, the reference works. If not, try dsonesuk's suggestion.On a related topic, it's worth remembering that IE often identifies line numbers incorrectly, especially if some lines are commented out.
Functi is in fact executed because I did put an alert there and it popd up. But I cannot use the argument(the event).
Link to comment
Share on other sites

note: I'm pretty sure all modern browsers display JS errors or have an error console that you can view to check them. Firefox, Safari, and Chrome definitely comes to mind (not including Firebug for FF).

Link to comment
Share on other sites

I recommend Firefox Error Console very highly, and explain how to use it in my member profile. But since the problem under consideration is the ##### IE window.event object, then it must be debugged in IE.

Link to comment
Share on other sites

This seems to work:var iframe = window.frames[0];e = e || iframe.event;EDIT: Funny thing is this doesn't:var iframe = document.getElementById("iFrame_test");This was what I tried first. Anybody know what the difference is between the two? I would think it would get a reference to the same object/element...EDIT 2: Ah ha!var iframe = document.getElementById("iFrame_test").contentWindow;This will get a reference to the iframe's window object, which is what window.frames[x] returns. getElementById only returns a reference to the HTML element, not the document within it.FWIW, contentDocument gets a reference to the iframe's document object.

Link to comment
Share on other sites

if you add the onmouseover="Functi(event)" to the link inline, it works fine, by adding by using unobtrusive method using onload you have to use addEventListener and attachEvent, well i had to anyway.so not only do you have to identify which browsers use contentDocument and contentWindow, but also which use addEventListener and attachEvent also (ie8 seems to use contentDocument same as FF, but uses attachEvent, good ol IE).Edit: also which browsers use target and srcElement

<script type="text/javascript"> /*<![CDATA[*//*---->*/ function Functi(e) {var event = e || window.event;var target = event.target || event.srcElement;alert(event.type);target.style.backgroundColor="lime";}window.onload=function(){var F = document.getElementById("myFrame"); if(F.contentDocument) { var anchorlink = F.contentDocument.getElementsByTagName('a');	anchorlink[3].style.color="orange";	if (F.addEventListener){  anchorlink[3].addEventListener("mousemove",Functi,false); } else if (F.attachEvent){  anchorlink[3].attachEvent("onmousemove",Functi);}		} else {var anchorlink = F.contentWindow.document.getElementsByTagName('a');   	anchorlink[3].style.color="orange";if (F.addEventListener){  anchorlink[3].addEventListener("mousemove",Functi,false); } else if (F.attachEvent){  anchorlink[3].attachEvent("onmousemove",Functi);}	}}   /*--*//*]]>*/ </script>

tested in ie6 - 8 (7 compatible), FF, and Opera.

Link to comment
Share on other sites

This was the code I used:

window.onload = function() {	var iframe = document.getElementById("iFrame_test").contentWindow.document;	iframe.getElementById("testBtn").onclick = alertTest;}function alertTest(e) {	var iframe = document.getElementById("iFrame_test").contentWindow;		e = e || iframe.event;	tempX = e.pageX || e.clientX + document.body.scrollLeft;	tempY = e.pageY || e.clientY + document.body.scrollTop;		alert("X position: "+tempX+"\nY position: "+tempY);}

It works in FF, IE, Opera, and Safari.EDIT: Oops, my previous version only worked in IE 8. I updated my code above so it now works in IE 8, IE 8 Compatibility View, and IE 7

Link to comment
Share on other sites

Thanks for your replies.thescientist, I didn't think that you can see errors in other browsers because I assumed that if they have errors, then they'll display them in the same way as IE, i.e. an icon at the bottom of your screen which when you click shows the error. I did just now come around an article which said that there is a shortcut to get an error console in FF. I tried it for this particular case, but it didn't show anything else useful besides what IE showed. It actually just repeated the error 20 times or so.Deirdre's Dad, alright, if it has some additional capabilities compared to IE, then I'll give it a try.dsonesuk, thanks for the code. I just put it in my code and made some appropriate changes and it worked well in IE and FF. I think it should also work in all other browsers (including Chrome) since it checks for all those browser specific attributes.ShadowMage, thanks for the code. I just tested it and it works well as well. I think that contentWindow doesn't work in Chrome according to w3schools. I, myself, don't have it installed yet so I cannot verify. It does say there as well that contentDocument is supported by Chrome so I may need to check for the support of the two features.By the way, your coordinates checking are rather shorter than mine (I do use coordinates in my page as well). However, if I use any other methods than what I have right now, the behaviour is pretty bad in FF. My page has a CSS hidden box which is revealed when I am on a particular link. This works well with your code in IE but in FF it keeps refreshing the box indefintely. I am not sure why this is the case, but that's how it is. My code for the coordinates is as follows, if you are interested:

var x=0;var y=0;var IE = document.all?true:false;if (IE) { // IE   /* get the mouse left position */   x = e.clientX + document.body.scrollLeft;   /* get the mouse top position */   y = e.clientY + document.body.scrollTop + 35;}else { // Netscape, Firefox, Opera */x = e.pageX;y = e.pageY + 35;}

A side note regarding the above: document.all is maybe not the best but it does work in every browser that I have checked.

Link to comment
Share on other sites

Can a moderator please remove the above posts
I hate spam. For the future, if you click on the "report" button to the bottom-left of a post, all moderators are notified by PM immediately, and can quickly respond.
Link to comment
Share on other sites

ShadowMage, thanks for the code. I just tested it and it works well as well. I think that contentWindow doesn't work in Chrome according to w3schools. I, myself, don't have it installed yet so I cannot verify. It does say there as well that contentDocument is supported by Chrome so I may need to check for the support of the two features.By the way, your coordinates checking are rather shorter than mine (I do use coordinates in my page as well). However, if I use any other methods than what I have right now, the behaviour is pretty bad in FF. My page has a CSS hidden box which is revealed when I am on a particular link. This works well with your code in IE but in FF it keeps refreshing the box indefintely. I am not sure why this is the case, but that's how it is.
I could not get contentWindow or contentDocument to work in Chrome. The odd thing is that if I use Chrome's debugging tools to inspect the iFrame I see both contentWindow and contentDocument listed as properties. contentDocument oddly enough however has a value of undefined, where as contentWindow is a window object like it's supposed to be. However, contentWindow.document consistently returns undefined even though it's listed in the properties of contentWindow as being a document object. :)Odd that my coordinates code doesn't work for you. Are your sure you're using it the same way? Your code does the exact same thing as mine just a little different syntax. You should be able to replace the code you posted with:tempX = e.pageX || e.clientX + document.body.scrollLeft;tempY = e.pageY || e.clientY + document.body.scrollTop;and it should work exactly the same.
Link to comment
Share on other sites

contentWindow or contentDocument do indeed work in chrome, as i have tested before in a previous posting involving iframes, but when targeting iframe body i used.contentDocument.documentElement.compared to.contentWindow.document.body.
Perhaps you could post some working code? I'd be interested to see what you have. I tried these three variations and all of them produce errors in Chrome:iframe = document.getElementById("iFrame_test").contentDocument.documentElement; //Cannot read 'documentElement' property of 'undefined'iframe = document.getElementById("iFrame_test").contentWindow.documentElement; //Cannot call method 'getElementById' of 'undefined'iframe = document.getElementById("iFrame_test").contentWindow.document.body; //Cannot read 'body' property of 'undefined'I'm using Chrome 7.0.517.41
Link to comment
Share on other sites

i used this a few years ago, so i don't know if the situation has changed since then with newer version of chrome

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" /><title>auto iframe height adjust</title><style></style><script type="text/javascript"><!--//function sizeFrame() {  var F = document.getElementById("myFrame"); if(F.contentDocument) {	F.height = F.contentDocument.documentElement.scrollHeight+30; //FF 3.0.11,  Opera 9.63, and Chrome } else {     			F.height = F.contentWindow.document.body.scrollHeight+30;  //IE6, IE7 and Chrome	  } } window.onload=sizeFrame; //--></script></head><body><iframe width="100%" id="myFrame" src="myframe.htm" scrolling="no" frameborder="0">An iframe capable browser isrequired to view this web site.</iframe></body></html>

Link to comment
Share on other sites

well i don't know whats happening, because i just downloaded chrome, had to change install to external hdrive, (really need new harddrive), and my old script, and your code did not show any undefined errors at all?
Hmm...That is indeed interesting. I wonder what happens for others. Maybe my installation is bad?
Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...