Forum Moderators: open
However, I have noticed that the same code also does not work now in Mozilla 1.7. It does work in Mozilla 1.6 and I've had it confirmed from a friend that 1.5 is fine too. It has worked in all Firefox browsers (so far), IE, Opera, Netscape 6 & 7, etc and until now Mozilla browser was fine too...
The odditiy is that on the first time the page is displayed it *usually* displays correctly. It is on revisits within the same browser session (ie, without me closing the browser down) that the problem shows itself.
Most of the code is on the other thread, but here it is again for this thread if anyone knows what might be the cause. I presume this is Mozilla tightening up on something I was doing wrong originally... like I say though, the strange thing is that it displays ok first time into my site?
html:
<div id="gig0" class="switchcontent">
<h3>heading</h3>
<div class="gigguide">
<p>contents</p>
</div>
</div>
<div id="gig1" class="switchcontent">
<h3>heading</h3>
<div class="gigguide">
<p>contents</p>
</div>
</div>
<a href="javascript:expandonegigs('gig0')">page 1</a>
<a href="javascript:expandonegigs('gig1')">page 2</a>
related snippets from the javascript:
function getObj(name) {
if (document.getElementById) {
this.obj = document.getElementById(name)
this.style = document.getElementById(name).style
} else if (document.all) {
this.obj = document.all[name]
this.style = document.all[name].style
}
}function contractallgigs(){
var inc=0
while (inc < totalgigs) {
var x = new getObj("gig"+inc)
x.style.display="none"
inc++
}
}function expandonegigs(gigid){
contractallgigs()
var x = new getObj(gigid)
x.style.display="block"
}function do_onload(){
expandonegigs('gig0')
}document.write('<style type="text/css">\n')
document.write('.switchcontent{display:none;}\n')
document.write('</style>\n')var agt = navigator.userAgent.toLowerCase();
var is_mac = (agt.indexOf("mac")!=-1);
var is_ie = ((agt.indexOf("msie")!=-1) && (agt.indexOf("opera")==-1));if (is_mac && is_ie) {
window.onload=do_onload
} else if (window.addEventListener){
window.addEventListener("load", do_onload, false)
} else if (window.attachEvent) {
window.attachEvent("onload", do_onload)
} else {
window.onload=do_onload
}
Once again, many thanks in advance for any pointers...
It may be that Moz 1.7 isn't recognizing the fact that the page has been reloaded [because it's coming from cache in the same session (?)]. The other day, Tribble was talking about forcing a 'soft' reload, and had some offerings in that area. I still can't find any info related to this (other than concerning users themselves).
It may be something like putting:
window.location.href = "_the page_url_" // or...
window.location.href = window.location.href //?!
This shouldn't force a reload, but might give the browser a nudge. Not a good prospect to have to put that in ALL your pages for EVER though.
Temporary workaround:
Trash everything pertaining to the onload event
[the assignments, and the do_onload function].
Put:
[blue]<script>
expandonegigs('gig0')
<script>
</html>[/blue]
..like that, at the very bottom of the page. The elements will then have loaded, and can be referenced immediately.
There is a possible questionmark of the resulting use of document.getElementById before the document has fully loaded "</html>", but I haven't seen problems yet, and this technique is known to be used.
What I'm wondering is whether getObj() should specify a return value of "this"?
What I'm wondering is whether getObj() should specify a return value of "this"?
(IMHO, as usual - but never trust MHO), No, it needn't return this - although it could.
getObj is being used as a constructor function to create Javascript objects that act as wrappers for elements. Constructors don't need to return this - and usually don't. Interesting technique, that used to be used for DHTML API's (like DynLayer). I hear that they've all stopped that now. Here, it is a complete waste of 'effort', since the function that calls the constructor, and acts on the wrapper..
1. accesses the same property names as the original elements.
2. then discards the object!
The only function the constructor performs is to get a useful, Xbrowser reference to the element. It could easily be replaced with:
function getObj(id)
{
if(document.all)
return document.all[id]
else if(document.getElementById)
return document.getElementById(id)
}
As far as efficiency is concerned, yes it is a big waste, but if you remember that drug-allegory episode, where Kirk and Spock get speeded up by aliens who exist on a faster time-frame, and can only be detected by the buzzing sound they make when they talk?
You'd have to be one of them to notice the difference.
Now, this "soft" reload thing...
Researching Flanagan's "JavaScript: The Definitive Guide", I found these passages that may be of interest:
"Keep in mind that a constructor function simply initializes the specified object; it does not have to return that object." And: "Constructor functions typically do not have return values. They initialize the object passed as the value of
thisand return nothing. However, a counstructor is allowed to return an object value, and, if it does so, that returned object becomes the value of the
newexpression. In this case, the object that was the value of this is simply discarded." Hmmm . . .
Objectively speaking, perhaps we could do with a few less objects flying about here. (That's not objectionable, is it?)
Also as you thought, still no success with Mozilla 1.7 which still works on first display but not on revisits.
I have a lot of confidence in the success to be gained from the first solution which was to replace the onload techniques with a small script at the end of the html... however, do you feel this is a script fault in that area or something unusual with the recent version of Mozilla?
Sorry about the little detour (which I believe I threatened last time).
Hmmm . . .
Hmmm.. indeed. What would be the point of all that?
I'm quite surprised that the author brings this barmy suggestion up, then leaves us to wonder. Is he just trying to confuse? Or is it a case of:
The treasure map...it's in the..[choke]..in the.....
Sucking on the soft flesh of a tomato brought a few ideas. The first isn't really what Flanagan is saying, and come to think, neither is the second.
1. return this
I have seen an instance in a constructor where, after doing something a bit "secret world of JS functions", returning this (as opposed to discarding it) made some critical difference. It's not that I don't remember so much as not getting it in the first place.
2. Create & attach, return element
Say we had a constructor, extender, whose prototype was packed with 40 or more handy methods. The object is attched to the element as it's e property, before the element itself is returned - and probably the object has a reference back to the element. The element now has access to all the methods via it's e property. This is wrapping turned partially inside out. Easily acheived, with no more code, by other means, and without a confusing use of new.
3. Create & discard, return element
Same as #2, but all the dandy methods are only needed during initialization. Some efficiency may be gained by properties and methods being somewhere around locally. Then, if you cared that much, you'd have a single global object for this, and not bother creating a new one each time.
It's still out there, on some tropical shore, buried under the hot sand.