Connecting Tech Pros Worldwide Forums | Help | Site Map

Hover Images Work in FF & NN, but not IE

RMWChaos's Avatar
Familiar Sight
 
Join Date: Oct 2007
Location: DFW, Texas, USA
Posts: 137
#1: Nov 10 '07
I have four pieces of code to automatically build my navigation buttons and choose which page to load: 1) a hover script, which swaps the images onmouseover and onmouseout, 2) a DOM loader, which automatically creates and removes DOM elements, 3) a nav script, which builds the nav buttons depending on the page being viewed, and 4) a page loader script that clears out the content area and inserts the newly selected content.

What should happen is this: NAVInit selects the images to use depending on the page being viewed, and submits them to the DOMLoader to remove the old elements and create the new elements. Part of the DOM creation process includes the attributes 'onmouseover=' and 'onmouseout=', which intiate the HOVERLoader script to swap out images, and an 'onclick=' attribute, which calls the PAGELoader script to load the new content and reset the nav buttons.

This all works in FF2.2.08 and NN9, but the onmouseover, onmouseout, and onclick do not work in IE7 (dang Microsoft again!). IE7 does not give any errors, however.

The strange thing is, I know that these three attributes all work in IE7 when the DOM Elements are created manually. So, what is going on here? The only thing that I can think of is in the way I create my strings. You'll see in the mouseOver and mouseOut vars I use in the NAVLoader script.

Not sure how much of the code you want to see, but I will try to include only the relevant parts. Because there is so much code here, I will add them in separate replies to this post.

Thanks in advance for your feedback.

RMWChaos's Avatar
Familiar Sight
 
Join Date: Oct 2007
Location: DFW, Texas, USA
Posts: 137
#2: Nov 10 '07

re: Hover Images Work in FF & NN, but not IE


HOVERLoader script:

Expand|Select|Wrap|Line Numbers
  1. function mouseHover(imagePath, imageId)
  2.  
  3.     {
  4.  
  5.     var image = document.getElementById(imageId);
  6.  
  7.     image.src = imagePath;
  8.  
  9.     };
  10.  
Simple enough.
RMWChaos's Avatar
Familiar Sight
 
Join Date: Oct 2007
Location: DFW, Texas, USA
Posts: 137
#3: Nov 10 '07

re: Hover Images Work in FF & NN, but not IE


DOMLoader script:

Expand|Select|Wrap|Line Numbers
  1. function removeDOM(id) // Remove DOM Elements Function //
  2.  
  3.     {
  4.  
  5.     var idExist = document.getElementById(id);
  6.  
  7.     if (idExist) // Delete child node. //
  8.  
  9.         {
  10.  
  11.         idExist.parentNode.removeChild(idExist);
  12.  
  13.         }
  14.  
  15.     else // Node does not exist, exit //
  16.  
  17.         {
  18.  
  19.         return;
  20.  
  21.         };
  22.  
  23.     };
  24.  
  25. function removeAllChildNodes(node) // Remove All Child Nodes from a Parent Node //
  26.  
  27.     {
  28.  
  29.     var parentExist = document.getElementById(node);
  30.  
  31.     if (parentExist && parentExist.hasChildNodes())
  32.  
  33.         {
  34.  
  35.         while (parentExist.childNodes.length > 0) // Remove the Child Nodes while the Parent Node has Them //
  36.  
  37.             {
  38.  
  39.             parentExist.removeChild(parentExist.firstChild);
  40.  
  41.             };
  42.  
  43.         }
  44.  
  45.     else // Parent does not exist or does not have child nodes //
  46.  
  47.         {
  48.  
  49.         return;
  50.  
  51.         };
  52.  
  53.     };
  54.  
  55. function createDOM(attrib) // Create DOM Elements Function //
  56.  
  57.     {
  58.  
  59.     var defaultAttribs = 
  60.  
  61.         {
  62.  
  63.         'dom'        :    'div',
  64.  
  65.         'parent'    :    'body'
  66.  
  67.         };
  68.  
  69.     for (var index in defaultAttribs) // Assign listed default attribs to 'undefined' attribs //
  70.  
  71.         {
  72.  
  73.         if(typeof attrib[index] == 'undefined')
  74.  
  75.             {
  76.  
  77.             attrib[index] = defaultAttribs[index];
  78.  
  79.             };
  80.  
  81.         };
  82.  
  83.     var idExist = document.getElementById(attrib.id);
  84.  
  85.     var createElement = document.createElement(attrib.dom);
  86.  
  87.     var parentExist = document.getElementById(attrib.parent);
  88.  
  89.     if (typeof attrib.id == 'undefined') // If 'id' is 'undefined', alert user and exit //
  90.  
  91.         {
  92.  
  93.         alert("There is no 'id' to create the node.");
  94.  
  95.         return;
  96.  
  97.         };
  98.  
  99.     if (attrib.dom == 'text') // Change createElement to createTextNode & assign parentExist to 'attrib.id' //
  100.  
  101.         {
  102.  
  103.         createElement = document.createTextNode(attrib.text);
  104.  
  105.         parentExist = document.getElementById(attrib.id);
  106.  
  107.         }
  108.  
  109.     else if (attrib.dom == 'script') // Assign parentExist to <head> //
  110.  
  111.         {
  112.  
  113.         parentExist = document.getElementsByTagName('HEAD')[0];
  114.  
  115.         };
  116.  
  117.     if (attrib.parent == 'body') // Assign parentExist to <body> //
  118.  
  119.         {
  120.  
  121.         if (document.getElementsByTagName) // W3C HTML DOM Level 1+ Standard (preferred method) //
  122.  
  123.             {
  124.  
  125.             parentExist = document.getElementsByTagName('BODY')[0];
  126.  
  127.             }
  128.  
  129.         else if (document.body) // Microsoft Implementation Shortcut //
  130.  
  131.             {
  132.  
  133.             parentExist = document.body;
  134.  
  135.             }
  136.  
  137.         else if (document.layers) // Netscape Navigator 4+ //
  138.  
  139.             {
  140.  
  141.             parentExist = document.tags['BODY'];
  142.  
  143.             }
  144.  
  145.         else // Alert user //
  146.  
  147.             {
  148.  
  149.             alert("Browser does not support known means to access <body>.");
  150.  
  151.             };
  152.  
  153.         }
  154.  
  155.     else if (!parentExist) // Create missing parent or target node first //
  156.  
  157.         {
  158.  
  159.         var body = document.getElementsByTagName('BODY')[0];
  160.  
  161.         var createParent = document.createElement('div');
  162.  
  163.         createParent.id = attrib.parent;
  164.  
  165.         body.appendChild(createParent);
  166.  
  167.         if (attrib.dom != 'text')
  168.  
  169.             {
  170.  
  171.             parentExist = document.getElementById(attrib.parent);
  172.  
  173.             };
  174.  
  175.         };
  176.  
  177.     if (parentExist) // Set attribs and create element //
  178.  
  179.         {
  180.  
  181.         if (attrib.dom != 'text')
  182.  
  183.             {
  184.  
  185.             createElement = document.createElement(attrib.dom);
  186.  
  187.             for (index in attrib)
  188.  
  189.                 {
  190.  
  191.                 createElement.setAttribute(index, attrib[index]);
  192.  
  193.                 };
  194.  
  195.             };
  196.  
  197.         parentExist.appendChild(createElement);
  198.  
  199.         };
  200.  
  201.     };
  202.  
Longer, but not really all that complex. Just a whole lot of 'if' and 'if...else' statements to cover as many possibilities as possible.
RMWChaos's Avatar
Familiar Sight
 
Join Date: Oct 2007
Location: DFW, Texas, USA
Posts: 137
#4: Nov 10 '07

re: Hover Images Work in FF & NN, but not IE


NAVLoader script:

Expand|Select|Wrap|Line Numbers
  1. var page = new Array("home", "guides", "specs", "links", "join", "news", "forum", "kills", "corp", "members");
  2.  
  3. var pageSelected = "home";
  4.  
  5. function navInit()
  6.  
  7.     {
  8.  
  9.     for (var x in page)
  10.  
  11.         {
  12.  
  13.         var imageId = "divnav" + page[x];
  14.  
  15.         var divNavExist = document.getElementById(imageId);
  16.  
  17.         if (divNavExist)
  18.  
  19.             {
  20.  
  21.             removeDOM(imageId);
  22.  
  23.             };
  24.  
  25.         if (pageSelected == page[x])
  26.  
  27.             {
  28.  
  29.             var pathSelected = "../images/selected" + page[x] + ".jpg"; 
  30.  
  31.             var alreadyHere = 'NavCon indicates that you are already here.';
  32.  
  33.             createDOM({
  34.  
  35.                 'dom'        :    'img',
  36.  
  37.                 'id'        :    imageId,
  38.  
  39.                 'alt'        :    alreadyHere,
  40.  
  41.                 'title'        :    alreadyHere,
  42.  
  43.                 'src'        :    pathSelected,
  44.  
  45.                 'onclick'    :    'alert("Is your NavCon malfunctioning? You are already here!")'
  46.  
  47.                 });
  48.  
  49.             }
  50.  
  51.         else if (pageSelected != page[x])
  52.  
  53.             {
  54.  
  55.             var altName = "Jump to " + page[x] + " sector";
  56.  
  57.             var pathHover = "../images/hover" + page[x] + ".jpg";
  58.  
  59.             var pathDefault = "../images/default" + page[x] + ".jpg";
  60.  
  61.             var mouseOver = "mouseHover('" + pathHover + "', '" + imageId + "')";
  62.  
  63.             var mouseOut = "mouseHover('" + pathDefault + "', '" + imageId + "')";
  64.  
  65.             var loadPage = "pageLoader(" + x + ")";
  66.  
  67.             createDOM({
  68.  
  69.                 'dom'        :    'img',
  70.  
  71.                 'id'        :    imageId,
  72.  
  73.                 'alt'        :    altName.capitalize(),
  74.  
  75.                 'title'        :    altName.capitalize(),
  76.  
  77.                 'src'        :    pathDefault,
  78.  
  79.                 'onmouseover'    :    mouseOver,
  80.  
  81.                 'onmouseout'    :    mouseOut,
  82.  
  83.                 'onclick'    :    loadPage
  84.  
  85.                 });
  86.  
  87.             };
  88.  
  89.         };
  90.  
  91.     };
  92.  
  93.  
A little more complex, but not too bad.
RMWChaos's Avatar
Familiar Sight
 
Join Date: Oct 2007
Location: DFW, Texas, USA
Posts: 137
#5: Nov 10 '07

re: Hover Images Work in FF & NN, but not IE


PAGELoader script:

Expand|Select|Wrap|Line Numbers
  1. function pageLoader(pageNum) // Initiate Page Selection
  2.  
  3.     {
  4.  
  5.     pageSelected = page[pageNum]; // Set var to the new page
  6.  
  7.     navInit(); // reset nav buttons using new pageSelected var
  8.  
  9.     removeAllChildNodes('content'); // clear the content area
  10.  
  11.     switch(pageNum) // load the new content
  12.  
  13.          {
  14.  
  15.          // several different cases depending on the nav button selected
  16.  
  17.          };
  18.  
  19.  
I shortened this one by not including all the switch cases.
Dasty's Avatar
Expert
 
Join Date: Nov 2007
Location: Slovakia
Posts: 101
#6: Nov 11 '07

re: Hover Images Work in FF & NN, but not IE


Quite a pain to read the whole stuff. But your problem is in how you assign event handlers to new created objects. No, IE has no problem with events on new created objects. After I digged your code i found that you basically are doing it like this:

[PHP]newElement.setAttribute('onclick','what to do in string format');
[/PHP]
You can not assign strings as event handler. I was even surprised that FF accepted it (and evalued it by default). The problem is, that you can assign just functions (refs). So to fast fix, you can do this:

[PHP]//instead:
newElement.setAttribute('onclick','what to do in string format');
//do this:
newElement.setAttribute('onclick',new Function('what to do in string format'));[/PHP]

(it will create anonymous function for each object)
RMWChaos's Avatar
Familiar Sight
 
Join Date: Oct 2007
Location: DFW, Texas, USA
Posts: 137
#7: Nov 11 '07

re: Hover Images Work in FF & NN, but not IE


Dasty,

Thank you very much for your time reviewing my code--I know it couldn't have been easy--and for your suggested fix. All my code is modular so that I don't have repeat multiple lines in each script. For instance, several different scripts use the DOMLoader and HOVERLoader scripts to generate content.

I thought the problem might be with my mouseOver, mouseOut, and pageLoader vars, just couldn't figure out what it was. I was under the impression that the string would be converted before DOMLoader added it as an attribute; guess not.

You are basically saying I should do this:

Expand|Select|Wrap|Line Numbers
  1. //instead of this
  2. onmouseover  :  mouseOver,
  3.  
  4. //do this
  5. onmouseover : new Function(mouseOver),
  6.  
That is a quick fix. Let me give it a try and I will report back the results.
RMWChaos's Avatar
Familiar Sight
 
Join Date: Oct 2007
Location: DFW, Texas, USA
Posts: 137
#8: Nov 12 '07

re: Hover Images Work in FF & NN, but not IE


Dasty,

That worked great in IE, but now FF and NN don't work. I did the fix two ways:

Expand|Select|Wrap|Line Numbers
  1. //first like this
  2. var mouseOver = new Function ("mouseHover('" + pathHover + "', '" + imageId + "')");
  3. onmousover   :   mouseOver
  4.  
  5. //then like this
  6. var mouseOver = "mouseHover('" + pathHover + "', '" + imageId + "')";
  7. onmousover   :   new Function (mouseOver)
  8.  
I suppose that I could include a browser check to see if it is IE, then include "new Function" in the mouseOver, mouseOut, and loadPage vars. That just seems a bit clunky to me. Perhaps there is another way.
RMWChaos's Avatar
Familiar Sight
 
Join Date: Oct 2007
Location: DFW, Texas, USA
Posts: 137
#9: Nov 12 '07

re: Hover Images Work in FF & NN, but not IE


Well, this is the code I ended up going with for now:

Expand|Select|Wrap|Line Numbers
  1. // This works only for MSIE
  2. if (navigator.appName == "Microsoft Internet Explorer")
  3.     {
  4.     var mouseOver = new Function("mouseHover('" + pathHover + "', '" + imageId + "')");
  5.     var mouseOut = new Function("mouseHover('" + pathDefault + "', '" + imageId + "')");
  6.     var loadPage = new Function("pageLoader(" + x + ")");
  7.     }
  8. // This works for Mozilla, FF, NN9, etc.
  9. else
  10.     }
  11.     var mouseOver = "mouseHover('" + pathHover + "', '" + imageId + "')";
  12.     var mouseOut = "mouseHover('" + pathDefault + "', '" + imageId + "')";
  13.     var loadPage = "pageLoader(" + x + ")";
  14.     };
  15.  
It works, but I would really like to know why one set of variables does not work for all browsers.

Perhaps the problem I should be working on instead is a better way to create my onmouseover, onmouseout, and onclick attributes.

I'm going for modularity and eliminating redundancy; so having to rewrite these vars twice really annoys me. :-|
Dasty's Avatar
Expert
 
Join Date: Nov 2007
Location: Slovakia
Posts: 101
#10: Nov 12 '07

re: Hover Images Work in FF & NN, but not IE


Quote:

Originally Posted by RMWChaos

Well, this is the code I ended up going with for now:

Expand|Select|Wrap|Line Numbers
  1. // This works only for MSIE
  2. if (navigator.appName == "Microsoft Internet Explorer")
  3.     {
  4.     var mouseOver = new Function("mouseHover('" + pathHover + "', '" + imageId + "')");
  5.     var mouseOut = new Function("mouseHover('" + pathDefault + "', '" + imageId + "')");
  6.     var loadPage = new Function("pageLoader(" + x + ")");
  7.     }
  8. // This works for Mozilla, FF, NN9, etc.
  9. else
  10.     }
  11.     var mouseOver = "mouseHover('" + pathHover + "', '" + imageId + "')";
  12.     var mouseOut = "mouseHover('" + pathDefault + "', '" + imageId + "')";
  13.     var loadPage = "pageLoader(" + x + ")";
  14.     };
  15.  
It works, but I would really like to know why one set of variables does not work for all browsers.

Perhaps the problem I should be working on instead is a better way to create my onmouseover, onmouseout, and onclick attributes.

I'm going for modularity and eliminating redundancy; so having to rewrite these vars twice really annoys me. :-|

No way. Do yourself a favor and forget that something like navigator.appName even exists. Nobody forces browser to identify itself right. Especially minor browsers are happy to identify themselves as one of the major browsers. So parsing appName is not the way - never. (google javascript browser identification and you'll find some more useful pseudo - solutions)

But back to your problem:

To be honest I am quite surprised of setAttribute behavior. I always thought that:

object[parameter_name] = value

is equivalent with:

object.setAttribute(parameter_name, value);

but obviously it is not. But I know, that obj.onclick = value; is working fine in all browsers. So try this (can not test it so check for typos):
[PHP]
for (index in attrib)
{
createElement.setAttribute(index, attrib[index]);
};
[/PHP]

change to:
[PHP]
for (index in attrib)
{
createElement[index] = attrib[index];
};
[/PHP]

It should work with events. (And ofc, use that new Function() for event handlers) Please run some tests and let us know.
gits's Avatar
Moderator
 
Join Date: May 2007
Location: Munich, Germany
Posts: 4,246
#11: Nov 12 '07

re: Hover Images Work in FF & NN, but not IE


Quote:

Originally Posted by Dasty

I always thought that:

Expand|Select|Wrap|Line Numbers
  1. object[parameter_name] = value;
  2.  
is equivalent with:

Expand|Select|Wrap|Line Numbers
  1. object.setAttribute(parameter_name, value);
but obviously it is not. But I know, that obj.onclick = value; is working fine in all browsers.

in some cases that seems to be equivalent ... but simply try it with the 'readonly' or 'disabled' attributes. there is a difference between setting an objects javascript-property (your first code) and setting an attribute of the dom-node (the second variation) ... in case you set the attribute 'readonly' with setAttribute(); you HAVE to remove it to make the node to accept input again ... we have to use removeAttribute() for that. we cannot set the attribute to false with set attribute here. but you may set the property node.readonly = false; BUT: with that we are mixing up the two ways ... and it is good practice to use ONE way to avoid confusion especially in case you have to debug your code later on :)

kind regards
Dasty's Avatar
Expert
 
Join Date: Nov 2007
Location: Slovakia
Posts: 101
#12: Nov 12 '07

re: Hover Images Work in FF & NN, but not IE


Quote:

Originally Posted by gits

in some cases that seems to be equivalent ... but simply try it with the 'readonly' or 'disabled' attributes. there is a difference between setting an objects javascript-property (your first code) and setting an attribute of the dom-node (the second variation) ... in case you set the attribute 'readonly' with setAttribute(); you HAVE to remove it to make the node to accept input again ... we have to use removeAttribute() for that. we cannot set the attribute to false with set attribute here. but you may set the property node.readonly = false; BUT: with that we are mixing up the two ways ... and it is good practice to use ONE way to avoid confusion especially in case you have to debug your code later on :)

kind regards

Good to know, did not know that (thank you). Makes sense now (i just thought that removeAttribute would be the same as "delete obj.property" ... but you can not delete obj.readOnly for example as you said). But while he can not use setAttribute for assigning event handlers and he can not assign all properties by just simple JS property assignment, then he has to divide events and attributes and work with them in different ways.
RMWChaos's Avatar
Familiar Sight
 
Join Date: Oct 2007
Location: DFW, Texas, USA
Posts: 137
#13: Nov 12 '07

re: Hover Images Work in FF & NN, but not IE


[quote=Dasty]change to:
[PHP]
for (index in attrib)
{
createElement[index] = attrib[index];
};
[/PHP]

Aha! You just solved a problem I was having that forced me to use the first method. I couldn't figure out how to set the index attribute because I had forgotten that .index is equiv to [index], and .index would not work. Now I can change that code and get around that problem.

I'll try it out and get back to you.
RMWChaos's Avatar
Familiar Sight
 
Join Date: Oct 2007
Location: DFW, Texas, USA
Posts: 137
#14: Nov 12 '07

re: Hover Images Work in FF & NN, but not IE


Alright, that worked in all browsers! Setting the dom-node attribute is exactly what I wanted to do in the first place (ergo "DOMLoader") ;-)).

Thank you for your help!
Reply