Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 6 of 6
  1. #1
    New to the CF scene
    Join Date
    Jul 2005
    Posts
    9
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Rollover function w/ array

    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:

    Code:
    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:

    Code:
    <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:

    Code:
    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.
    Last edited by markcholden; 07-11-2005 at 04:22 PM. Reason: forgot to put proper title

  • #2
    Supreme Master coder! glenngv's Avatar
    Join Date
    Jun 2002
    Location
    Philippines
    Posts
    11,043
    Thanks
    0
    Thanked 251 Times in 247 Posts
    You can do it by using custom attribute.
    Code:
    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
        ..
    }
    
    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.

    Code:
    for (var i=0;i<tags1.length;i++)
    {
      tags1[i].onmouseover = mOver; //not anonymous function to avoid IE memory leak
      ..
    }
    
    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';
    }

  • #3
    New to the CF scene
    Join Date
    Jul 2005
    Posts
    9
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Brilliant! It works perfectly. Thank you so much.

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

    Code:
    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!

  • #4
    Supreme Master coder! glenngv's Avatar
    Join Date
    Jun 2002
    Location
    Philippines
    Posts
    11,043
    Thanks
    0
    Thanked 251 Times in 247 Posts
    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.
    Code:
    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.

  • #5
    New to the CF scene
    Join Date
    Jul 2005
    Posts
    9
    Thanks
    0
    Thanked 0 Times in 0 Posts
    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.

  • #6
    Supreme Master coder! glenngv's Avatar
    Join Date
    Jun 2002
    Location
    Philippines
    Posts
    11,043
    Thanks
    0
    Thanked 251 Times in 247 Posts
    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.


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •