...

View Full Version : Rollover function w/ array



markcholden
07-11-2005, 04:21 PM
I'm working on a company's website's intro page, and I'm trying to make rollovers with the information stored in an array. The rollovers are attached using a modification of Peter-Paul Koch's script, like so:


function setBehavior()
{
if (!W3CDOM) return;

var nav1 = document.getElementById('main_mouseovers');
var tags1 = nav1.getElementsByTagName('li');

for (var i=0;i<tags1.length;i++)
{
tags1[i].onmouseover = function() { main_toggleOn(i); }
tags1[i].onmouseout = function() { main_toggleOff(i); }
tags1[i].onclick = function() { window.location.href = page[i] + '.html'; }
}
}

What I'm trying to do is change the class of the nav <a>, the class of the nav <li>, the visibility of an image on the side, and then change that image's source when a user rolls over a navigational link. The relevant XHTML code is as follows:


<img id="dynimg" class="hide hidden" style="visibility: hidden;" src="spacer.gif" alt="" height="300" width="300" />

<ul id="main_mouseovers">

<li id="index_li">
<a id="index" href="index.html">Home</a>
</li>

<li id="services_li">
<a id="services" href="services.html">Services</a>
</li>

<li id="news_li">
<a id="news" href="news.html">News</a>
</li>

<li id="employment_li">
<a id="employment" href="employment.html">Employment</a>
</li>

<li id="links_li">
<a id="links" href="links.html">Links</a>
</li>

<li id="contact_li">
<a id="contact" href="contact.html">Contact</a>
</li>

</ul>

That part doesn't seem to be the problem, though. It knows to run the function on mouseover, all right, but reports this error:


document.getElementById(elmt) has no properties

In addition, although no error is reported, the source of the image "dynimg" doesn't change to anything the browser can use. IE displays a broken image icon; Firefox does nothing. Also, when I change "document.getElementById(elmt)" to "document.getElementById(page[i])" it says "page has no properties".

The relevant JavaScript:


var page = new Array(6);
page[0]='index';
page[1]='services';
page[2]='news';
page[3]='employment';
page[4]='links';
page[5]='contact';

var imgs = new Array();
for (var i=0;i<page.length;i++) { imgs[i] = new Image(); imgs[i].src = 'splash_' + page[i] + '.jpg'; }

function main_toggleOn(i)
{
elmt = page[i];
document.getElementById('dynimg').style.visibility = 'visible';
document.getElementById('dynimg').src = imgs[i];
document.getElementById(elmt).className = 'hover';
document.getElementById(elmt + '_li').className = 'hover';
}

function main_toggleOff(i)
{
elmt = page[i];
document.getElementById('dynimg').style.visibility = 'hidden';
document.getElementById('dynimg').src = 'spacer.gif';
document.getElementById(elmt).className = 'fix';
document.getElementById(elmt + '_li').className = 'fix';
}

I intend to simplify it down to a single toggle function in the future, but for now I'm being as verbose as possible for construction purposes. And it's not working. All the code appears correct to my eyes, but it's not working. What am I missing? Any help appreciated. Thanks.

glenngv
07-12-2005, 03:30 AM
You can do it by using custom attribute.

for (var i=0;i<tags1.length;i++)
{
tags1[i].index = i; //create a custom attribute to the li's
tags1[i].onmouseover = mOver; //not anonymous function to avoid IE memory leak (http://www.bazon.net/mishoo/articles.epl?art_id=824)
..
}

function mOver(){
alert(this.index);
main_toggleOn(this.index);
}
But custom attributes are not standards.
Other solution that I recommend over custom attribute is this. Since you have a naming convention for your list that associates to a particular link, you can use the list id as parameter and just let main_toggleOn() function to extract the link id from it. No need for the array.


for (var i=0;i<tags1.length;i++)
{
tags1[i].onmouseover = mOver; //not anonymous function to avoid IE memory leak (http://www.bazon.net/mishoo/articles.epl?art_id=824)
..
}

function mOver(){
main_toggleOn(this.id);
}

function main_toggleOn(listId)
{
var linkId = listId.replace(/_li/, ""); //extract link id from listId
document.getElementById('dynimg').style.visibility = 'visible';
document.getElementById('dynimg').src = imgs[i];
document.getElementById(linkId).className = 'hover';
document.getElementById(listId).className = 'hover';
}

markcholden
07-12-2005, 03:42 PM
Brilliant! It works perfectly. Thank you so much. :D

The complete code follows. Any further comments on simplification, optimization, syntax, etc. welcome.


var W3CDOM = (document.createElement && document.getElementsByTagName && document.getElementById);

window.onload = setBehavior;

function setBehavior()
{
if (!W3CDOM) return;

main_nav = document.getElementById('main_mouseovers');
main_tags = main_nav.getElementsByTagName('li');
left_nav = document.getElementById('left_mouseovers');
left_tags = left_nav.getElementsByTagName('p');

left_spans = new Array();
for (var i=0;i<left_tags.length;i++) { left_spans[i]=left_tags[i].id.replace('_m',''); }

//preload images
var imgs = new Array();
for (var i=0;i<left_spans.length;i++) {
imgs[i] = new Image();
imgs[i].src = 'splash_' + left_spans[i] + '.jpg';
}

for (var i=0;i<main_tags.length;i++)
{
main_tags[i].onmouseover = myToggleM;
main_tags[i].onmouseout = myToggleM;
}
for (var i=0;i<left_tags.length;i++)
{
left_tags[i].onmouseover = myToggleL;
left_tags[i].onmouseout = myToggleL;
}

togglers = new Array();
togglers[0]= 'ic_main';
togglers[1]= 'copyright';

var hiders = new Array();
hiders[0]= 'subcontent';
hiders[1]= 'llc';
hiders[2]= 'main_mouseovers';
hiders[3]= 'llc';
for (var i=0;i<hiders.length;i++) {
id=document.getElementById(hiders[i]);
id.onmouseover = hideLeft; }

hideLeft();
}

function myToggleM() { main_toggle(this.id); }
function myToggleL() { left_toggle(this.id); }

function main_toggle(listId)
{
hideLeft(); //make sure there are no display glitches

var linkId = listId.replace('_li',''); //extract link id from listId

var theimg = document.getElementById('dynimg');
var imgsrc; var hover; var j;

(theimg.style.visibility=='visible') ? j=0 : j=1;

(j==0) ? imgsrc='spacer.gif' : imgsrc = 'splash_' + linkId + '.jpg';
(j==0) ? hover='fix' : hover='hover';

toggleVis('dynimg');
theimg.src = imgsrc;
chgClass(linkId,hover); chgClass(listId,hover);
}

function left_toggle(pId)
{
hideLeft();

var spanId = pId.replace('_m','');
var textId = spanId + '_text';

for (var i=0;i<togglers.length;i++) { toggleDisp(togglers[i]); }

toggleDisp(spanId); toggleDisp(textId);
}

function hideLeft() {
toggleDisp('ic_main','block');
toggleDisp('copyright','block');
for (var i=0;i<left_spans.length;i++) {
toggleDisp(left_spans[i],'none');
toggleDisp(left_spans[i] + '_text','none');
}
}



function toggleVis(id,opt)
{
var elmt = document.getElementById(id);
if (!opt) { (elmt.style.visibility=='visible') ? opt='hidden' : opt='visible'; }
elmt.style.visibility = opt;
}

function toggleDisp(id,opt)
{
var elmt = document.getElementById(id);
if (!opt) { (elmt.style.display=='none') ? opt='block' : opt='none'; }
elmt.style.display = opt;
}

function chgClass(id,cls) { document.getElementById(id).className=cls; }

The actual page contains two separate sections with distinct rollover effects.

Thanks again!

glenngv
07-13-2005, 03:03 AM
I advice you to always declare variables with var keyword if you want them with local scope. Any variable declared without the var keyword automatically becomes global. Not using the var keyword may lead to unexpected results like this.

function func1(){
for (i=0;i<10;i++){
func2();
}
}

function func2(){
for (i=10;i>0;i--){
//
}
}

The code above will cause an endless loop because i will always be reset to 0 when func2() is called.

markcholden
07-13-2005, 03:07 AM
I deliberately did not use local vars because I wanted them to be accessible to other functions down the line, e.g. hideLeft(); which uses left_spans even though left_spans is created in the onload function. Thanks, though.

glenngv
07-13-2005, 03:59 AM
Then it's good to declare it outside the function to make it clear, especially if other developers will modify your code in the future. :)



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum