PDA

View Full Version : Switch Content on Mac IE 5.1 onload



rubycat
04-27-2005, 12:33 AM
Script: Switch Content
http://www.dynamicdrive.com/dynamicindex17/switchcontent.htm

The Switch Content script is just a thing of beauty! Of course, I have run into a teeny problem in IE 5.1 for the Mac.

I'm putting this into a page which already has an onload event attached to the <body> tag.

Generally speaking, I know I have to remove the onload statement from a javascript and add it directly to the body tag if I want to use it on a page whose body tag already has an onload event. Never had a problem with this before but now I am stymied.

Towards the very end of the Switch Content javascript is the following:

if (window.addEventListener)
window.addEventListener("load", do_onload, false)
else if (window.attachEvent)
window.attachEvent("onload", do_onload)
else if (document.getElementById)
window.onload=do_onload

I get that these three statements are there to deal with the different browsers but the script fails on the Mac IE 5.1 because (I think), like I said, I already have an onload event on the page.

I figured this out because if I add "do_onload" to the body tag of the page, it works and nothing seems to blowup in Firefox or IE6.0 (WIN) but is this the right way to go about getting this to work? And should't I be removing something frm the above snippet if I am moving the onload statement out of the script and into the page?

I don't know how to do it with this particular script since the above snippet is kind of one of those if/else/else thingamajigs.

Am I making any sense? Any help would be much appreciated...I am just in love with this script.

jscheuer1
04-27-2005, 07:41 AM
There has to be a more succint way but, without testing, this should work:


<body onload="yourotherthing();if ((!window.addEventListener)&&(!window.attachEvent)){do_onload()}then in the script, change the code block you have in your post to:


if (window.addEventListener)
window.addEventListener("load", do_onload, false)
else if (window.attachEvent)
window.attachEvent("onload", do_onload)

mwinter
04-27-2005, 12:15 PM
if (window.addEventListener)
window.addEventListener("load", do_onload, false)
else if (window.attachEvent)
window.attachEvent("onload", do_onload)
else if (document.getElementById)
window.onload=do_onload

I get that these three statements are there to deal with the different browsers but the script fails on the Mac IE 5.1 because (I think), like I said, I already have an onload event on the page.Indeed. If either of the first two branches are taken (IE5+/Win, or DOM-conforming user agents) the event listener will be added to an internal list of functions to be called when the load event fires. The only way to remove these listeners is with the removeEventListener or detachEvent methods. Though attachEvent is something that Microsoft invented, it wasn't implemented on the Mac, so instead, IE/Mac will take the third branch.

However, the onload property is effectively the same as the onload attribute on the body element. When a user agent gets around to parsing that element, it will overwrite the existing listener.


There has to be a more succint way but, without testing, this should work:


<body onload="yourotherthing();if ((!window.addEventListener)&&(!window.attachEvent)){do_onload()}Maintaining the semantics of the original script:


<body onload="yourotherthing(); if(document.getElementById) {do_onload();}">and the complete removal of all branches of the original if statement.

Mike

jscheuer1
04-27-2005, 05:26 PM
Maintaining the semantics of the original script:

<body onload="yourotherthing(); if(document.getElementById) {do_onload();}">That will maintain the semantics, yes. It, if I followed the original post on this correctly, will not do beans for IE5 Mac though.

mwinter
04-27-2005, 06:18 PM
That will maintain the semantics, yes. It, if I followed the original post on this correctly, will not do beans for IE5 Mac though.It certainly should. Based on the OP's description, the document in question will look something like:


/* Rest of script */
if (window.addEventListener)
window.addEventListener("load", do_onload, false)
else if (window.attachEvent)
window.attachEvent("onload", do_onload)
else if (document.getElementById)
window.onload=do_onload
</script>
</head>

<body onload="/* ... */">As I said previously, IE/Mac will not execute either of the first two branches, so that effectively produces:


/* Rest of script */
if (document.getElementById)
window.onload=do_onload
</script>
</head>

<body onload="/* ... */">or
/* Rest of script */
if (document.getElementById) {window.onload=do_onload;}
window.onload = function() {
/* ... */
};
</script>
</head>

<body>So as you can see, the event listener specified by the body element overwrites do_onload. This is the cause of the problem, not the involvement of getElementById, which IE/Mac does support. If it didn't, the script wouldn't work at all.

Mike

rubycat
04-27-2005, 09:28 PM
Mike and jscheuer1--thank you both for your help. I implemented jscheuer's solution this morning and everything worked great. For some reason, I didn't receive any more e-mail notifications informing me that further posts had been made so I only saw the rest of this thread now. I have since implemented Mike's code and again, everything seems hunky dory.

Hate to admit it but your discussion confused me so may I just confirm--I use the semantically-correct version of jscheuer1's code that Mike provided and completely eliminate the whole chunk of code that I included in my original post?

Thanks in advance for the clarification and the help.

jscheuer1
04-28-2005, 01:51 AM
Without access to IE5 Mac for testing and having not tested the effect it will have on other browsers, I'd stick with my solution if it works and causes no problems. Mike's explanations can be hard to follow sometimes and sometimes he assumes one knows things one may or may not know. That being said, he's usually right though, once he fully explains himself. He'll probably weigh in here sooner or later, so check back.

mwinter
04-28-2005, 10:08 AM
[...] I'd stick with my solution if it works and causes no problems.It will work, but it may cause problems. The criteria for executing do_onload in the load intrinsic event listener with your code is just that the user agent doesn't support either addEventListener or attachEvent. That will catch a lot of older user agents. As the script lacks any kind of meaningful internal feature detection, run-time errors may result. Hardly impressive when so easily avoidable.

Whilst just testing for document.getElementById is hardly sufficient[1], it's better than nothing. I can guarantee that the solution I offered will have no adverse affects on user agents that already ran this code. In fact, the suggestion will prevent IE4 from running the code; a good thing as IE4 doesn't support said method.

To the OP, follow the three steps below. I'll go from your first attempt, where you just had the initialisation code for the ther script in the onload attribute.


Make sure that the code in the onload attribute ends with semicolon (;). For example, change
<body onload="myFunction()">to
<body onload="myFunction();">
Paste the code below after that semicolon.
if(document.getElementById) {do_onload();}The attribute would now read:
[html]<body onload="myFunction(); if(document.getElementById) {do_onload();}">
Remove the if..else structure
if (window.addEventListener)
window.addEventListener("load", do_onload, false)
else if (window.attachEvent)
window.attachEvent("onload", do_onload)
else if (document.getElementById)
window.onload=do_onloadfrom the script.
Mike


[1] Feature detection should involve as close to 1:1 relationships as possible. For example, just because getElementById is supported, one cannot immediately assume that getElementsByTagName is, too. That said, it is reasonable to assume that paired properties, like clientX and clientY, are both supported if one of them is found.

shal187
04-28-2005, 01:22 PM
hey i am trying to make this script more than 1 level deep: for example

menu1
--submenu1
----item here
--submenu2
----item here
menu2
--submenu2
----item here

now ive got it so that when i click on menu1-submenu1 the submenu 2 will collapse, and when i click on submenu2 submenu1 will collapse... but cannot figure out how to get it so that if menu1 is open and i click on menu2, menu1 will collapse... any help would be appreciated...

here is how it is currently set up:


function do_onload(){
uniqueidn=window.location.pathname+"firsttimeload"
var alltags=document.all? document.all : document.getElementsByTagName("*")
ccollect=getElementbyClass(alltags, "travbody")
statecollect=getElementbyClass(alltags, "showstate")
if (enablepersist=="on" && ccollect.length>0){
document.cookie=(get_cookie(uniqueidn)=="")? uniqueidn+"=1" : uniqueidn+"=0"
firsttimeload=(get_cookie(uniqueidn)==1)? 1 : 0 //check if this is 1st page load
if (!firsttimeload)
revivecontent()
}
if (ccollect.length>0 && statecollect.length>0)
revivestatus()
}

and here is how i have the items set up....


<div class="travhead" onClick="javascript:sweeptoggle('contract') & expandcontent(this, 'logon1') & expandcontent(this, 'logon2')& expandcontent(this, 'logon3') & expandcontent(this, 'logon4') & expandcontent(this, 'logon5') "
style="cursor:hand; cursor:pointer">START-UP</div>
<div class="travsub" id="logon1" onclick="expandcontent(this, 'slogon1')" style="cursor:hand; cursor:pointer">Log
In to Tr@veller</div>
<div class="travbody" id="slogon1">

rubycat
05-02-2005, 06:09 PM
Ugh. Me again. Quick question...

My pages which use this script--in the status bar at the bottom of the browser window in WIN Firefox--it always displays "Waiting for http://whatever.com" as opposed to, for example, in WIN Explorer which says "Done."

Is there something weird going on? Like, what's it waiting for? Godot? Has anyone else seen this behavior? It doesn't happen to me when I am at the Dynamic Drive site viewing the Switch Content script so I am wondering if that "onload magic" I needed help with could perhaps be interfering with something?

jscheuer1
05-02-2005, 06:56 PM
That usually happens with slideshow scripts. Do you also have a slideshow on the page?

rubycat
05-02-2005, 07:06 PM
No...the other script is for a menu system which enables the menu to open to the menu item which the page represents and apply some CSS styling to it (two onload thingies). I also just realized...I forgot...I have this script on another web site also and in Firefox, the status bar reads: "Transferring data from http://whatever.com" and also, never stops doing that. A tad different, huh? Both web sites are using the same menuing system/javascript. Whaddya' think...?

mwinter
05-02-2005, 07:22 PM
I have this script on another web site also and in Firefox, the status bar reads: "Transferring data from http://whatever.com" and also, never stops doing that.To expand on what John was referring to, any script which causes dynamic loading, especially image data for rollovers and the like, can cause this message to appear. You can't get rid of it, but it doesn't do any harm (just looks a little odd).

Mike