Nicolas R

Navigation

Skip navigation.

Search

Site navigation

Email conversation

FromNicolas R
ToMe
SubjectStrange problem with Javascript cookies and .className function
Date22 March 2006 20:40
Hi Mark,
I'm Nick and I'm having a very strange problem with a javascript I'm
writting. This is my first attempt to create a script from scratch
(almost) and that's why I'm very puzzled about this.
The demo is on this page: [URL]

The main problem is in line 40 and I have included a small explanation there.

The script works as follows:
1) When the page loads, all the child elements in a specified parent
element are assigned as "inactive" (display:none in the CSS) except
the first one
2) While this happens, the script creates an array with all the child
elements and their ID
3) If a cookie exists, it expands the element defined in the cookie
(.className='active') and it should highlight the corresponding link
(again, .className='active')
4) If a cookie does not exist, it highlights the first link so that to
correspond with the first expanded element
5) When a user clicks on a link, the link and the element the user
whises to display are passed to the script
6) The script first hides all elements, creates a cookie on which tab
the user is currently seeing, highlights the link he clicked, and then
shows the correct element

The problem is here.. When a user clicks on a link to expand an
element, the script correctly changes the link's class to 'active'
(and the class of all other links to 'inactive')
However, when the page is loaded and a cookie exists even though the
correct element is displayed (according to the cookie), and even
though the function to highlight the corresponding link is called when
the correct element is displayed, the link's class will not change. I
have no idea why this happens. All the variables seem to be ok. It
should work ok in both instances (when the user clicks on a link and
then the page is reloaded) because the function is called with the
same variables.

So, the main problem is line 40, presumably.
I think only functions loadGallery(line 16), showImage(31) and
highlightLink(36) are relevant to this problem

Alright, thanks a lot mate, hopefuly you will get this message and be
able to give a hand here

Cheers
FromMe
ToNicolas R
SubjectRe: Strange problem with Javascript cookies and .className function
Date23 March 2006 17:31
Nicolas,

> However, when the page is loaded and a cookie exists even though the
> correct element is displayed (according to the cookie), and even
> though the function to highlight the corresponding link is called when
> the correct element is displayed, the link's class will not change.

Your problem is that you have overestimated the capabilities of cookies.
Cookies only understand strings. You are passing it a reference to a link
and asking it to store it. It can't store a reference to an object, so it
tries to store a string representation of the object (in most browsers, it
stores the href of the link).

What you need to do is to give each link an ID, and store that. Then when
you retrieve the cookie, use document.getElementById to turn it back into a
reference to the link.


Mark 'Tarquin' Wilton-Jones - author of http://www.howtocreate.co.uk/
FromNicolas R
ToMe
SubjectRe: Strange problem with Javascript cookies and .className function
Date23 March 2006 17:39
Mark,
thank you for your quick reply!
I have just updated the script, modified the css a bit and added a
"previous" "next" function   (but the cookie problem still exists).

I would prefer it if I could do this without adding extra markup in
the HTML, but if that's the best method I would go for it. Isnt there
a way to retrieve the object, given that I already have the link from
the cookie?

Cheers
FromMe
ToNicolas R
SubjectRe: Strange problem with Javascript cookies and .className function
Date23 March 2006 18:02
> I would prefer it if I could do this without adding extra markup in
> the HTML, but if that's the best method I would go for it. Isnt there
> a way to retrieve the object, given that I already have the link from
> the cookie?

Sure, but maybe a little messy (even though it keeps the HTML clean).

Basically, you need to store the linkobject.hash. Then since your cookie now
has the link hash, when the page loads, check all links (cycle through the
document.links array or getElementsByTagName('a') NodeList), and if the hash
of a link matches the stored hash, then that is the right one.

As long as you do not have hundreds of links, the script should run fast
enough.

Note that some browsers incorrectly give a blank hash, but that should not
matter too much, since the page remains accessible.
FromNicolas R
ToMe
SubjectRe: Strange problem with Javascript cookies and .className function
Date23 March 2006 19:46
Mark, thank you for your reply
I did what you said and it works just fine!!:) The previous next also
works now, cheers mate!
It seems however that the script takes a bit to run through, for a
second you can see the other images before the script changes their
className.

I'm sure there are a lot of ways to get the whole script running with
less code and html markup, but what's the most obvious "useless" code
you can spot and be removed so that to minimise the time needed for
the script to run?

Many thanks, cheers
FromMe
ToNicolas R
SubjectRe: Strange problem with Javascript cookies and .className function
Date23 March 2006 20:09
Nicolas,

> I'm sure there are a lot of ways to get the whole script running with
> less code and html markup, but what's the most obvious "useless" code
> you can spot and be removed so that to minimise the time needed for
> the script to run?

to be honest, your script runs very quickly. That is not the actual problem.
The reason you see the layout changing is because you wait for onload to
fire. This will only fire after the displayed images have loaded, so it can
take a while.

What you want to do is to run the script as early as possible, so that it
does not have to wait for onload, and is able to run as soon as the page has
been processed, and is in the process of being displayed.

(There is a proprietary event called DOMContentLoaded, that a couple of
browsers can use, but that is not supported well enough for real Web pages.)

The easiest way to run this early is to stop using load event listeners, and
instead, just run your script immediately before the </body> tag.

Remove this:

if (window.addEventListener){...
...
else if (document.getElementById){window.onload=loadGallery;}

and use this instead:

<script type="text/javascript">
loadGallery();
</script>
</body>
</html>


It is not a perfect solution, but the script should run a lot earlier.
FromNicolas R
ToMe
SubjectRe: Strange problem with Javascript cookies and .className function
Date23 March 2006 22:04
> So how do you find the script?

honestly very good. The way it links to the anchors is one of my personal
favourites due to the way it degrades to produce predictable and sensible
behaviour - I use the same technique where I can.

I have only one small criticism; the cookie retrieval script could
potentially make mistakes if document.cookie was like this:

bazfoo=bar; foo=buzz;

if you look for "foo" you will get the wrong one. However, that should not
matter with the cookie names you are using, and it is a _very_ common
mistake made by almost all cookie scripts, so you are certainly not alone.

since your cookie names are ok, there is no need to change it, but for more
generic use, it is important to make sure you do not fall into that trap.
The easy way to avoid it is to use split() to get each name=value pair, then
again to break that into a separate name and value. You can then perform an
exact match on the names to find the one that matches. If you are
interested, I have more details in my tutorial:
http://www.howtocreate.co.uk/tutorials/javascript/cookies
FromMe
ToNicolas R
SubjectJavaScript error: indexOf problem with Opera & IE but not with Firefox
Date9 May 2006 20:09
Hey Mark,
I've sent you an e-mail a while ago and since you were very helpfull I
decided to ask you once again. I have no idea why this problem occurs,
especially since it occurs in Opera and IE while Firefox seems to do just
fine.

The error as described in Opera is as follows:
Error:
name: TypeError
message: Statement on line 98: Type mismatch (usually a non-object value
used where an object is required)
Backtrace:
 Line 98 of linked script [URL]
   if (setEasyCompleteForElements.indexOf(getInputs[y].nodeName.toLowerCase())
!= - 1)

The error is in a line which uses indexOf to determine whether there's a
need to check certain types of elements. There's an array of types of
elements (eg 'input','textarea' ... ) and the script uses indexOf to
determine if an element in the XHTML document is included in that array.
I've searched your site for any comments on problems with indexOf and I
couldnt find anything, so theres probably something wrong in the way I used
it.

I hope you will find the comments in the script helpful in determining what
the problem is. The errors are in lines 98 (and maybe 101) and 131.

Thank you very much :)
FromNicolas R
ToMe
SubjectRe: JavaScript error: indexOf problem with Opera & IE but not with Firefox
Date9 May 2006 17:01
Nicolas,

> it occurs in Opera and IE while Firefox seems to do just fine.

This caught me a little by surprise, but the reason is fairly simple. You
are using the .indexOf method on an array, not a string. indexOf is a method
of string objects, not array objects. For some reason, Mozilla/Firefox
implements it on arrays as well. That is an extension, so do not use it. If
you want to check for the existence of a value inside an array, you should
write your own function to check them:

function hasValueInside(oNeedle,oHaystack) {
  for( var i = 0; i < oHaystack.length; i++ ) {
    if( oNeedle == oHaystack[i] ) { return true; }
  }
  return false;
}
...
if(hasValueInside(getInputs[y].nodeName.toLowerCase(),
  setEasyCompleteForElements)){
This site was created by Mark "Tarquin" Wilton-Jones.
Don't click this link unless you want to be banned from our site.