SitePoint Sponsor

User Tag List

Results 1 to 12 of 12
  1. #1
    SitePoint Guru Chroniclemaster1's Avatar
    Join Date
    Jun 2007
    Location
    San Diego, CA
    Posts
    784
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Condensing unobtrusive event handlers

    Hi!

    I'm trying to condense the following code...

    Code:
    //Trigger On functions when main menu divs are moused over
    document.getElementById("specificButton01").onmouseover = function() {driveMenu("specific", 1, "on")};
    document.getElementById("specificButton02").onmouseover = function() {driveMenu("specific", 2, "on")};
    document.getElementById("specificButton03").onmouseover = function() {driveMenu("specific", 3, "on")};
    document.getElementById("specificButton04").onmouseover = function() {driveMenu("specific", 4, "on")};
    document.getElementById("specificButton05").onmouseover = function() {driveMenu("specific", 5, "on")};
    document.getElementById("specificMenu01").onmouseover = function() {driveMenu("specific", 1, "on")};
         .
         .
         .
    Including the second navbar there are a total of 40 event handlers checking 20 divs to turn 10 divs on and off. I think there's got to be a cleaner way to do this, but I don't know if there's a way or not. I was hoping a series of nested
    loops would do the trick, but so far I can't even get a single loop to
    run through the first batch of buttons. I've tried experiements along
    these lines.


    Code:
    for (i=1, i<6, i++) {
    
         document.getElementById("specificButton0" + i).onmouseover = function() {driveMenu("specific", i, "on")};
    }
    But I'm getting undefined errors, and I'm afraid that by creating the statements in a loop like this, they may not be constructed when the events occurs, hence the undefined. Is there a syntax to accomplish this? A set of two or three nested for loops would eliminate a lot of redundant code.
    Whatever you can do or dream you can, begin it.
    Boldness has genius, power and magic in it. Begin it now.

    Chroniclemaster1, Founder of Earth Chronicle
    A Growing History of our Planet, by our Planet, for our Planet.

  2. #2
    SitePoint Guru
    Join Date
    Sep 2006
    Posts
    731
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Chroniclemaster1 View Post
    I've tried experiements along
    these lines.[/SIZE]

    Code:
    for (i=1; i<6; i++) {
    
         document.getElementById("specificButton0" + i).onmouseover = function() {driveMenu("specific", i, "on")};
    }
    But I'm getting undefined errors, and I'm afraid that by creating the statements in a loop like this, they may not be constructed when the events occurs, hence the undefined. Is there a syntax to accomplish this? A set of two or three nested for loops would eliminate a lot of redundant code.
    Try this:
    Code:
    for(var i=1; i<6; i++) 
     document.getElementById("specificButton0" + i).onmouseover = new Function('driveMenu("specific", ' + i + ', "on")');
    Last edited by Logic Ali; Aug 28, 2007 at 06:17.
    Tab-indentation is a crime against humanity.

  3. #3
    SitePoint Author silver trophybronze trophy

    Join Date
    Nov 2004
    Location
    Ankh-Morpork
    Posts
    12,159
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Shouldn't for(var i=1, i<6, i++) be for(var i=1; i<6; i++)?
    Birnam wood is come to Dunsinane

  4. #4
    I meant that to happen silver trophybronze trophy Raffles's Avatar
    Join Date
    Sep 2005
    Location
    Tanzania
    Posts
    4,662
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    It would be neater to do this:
    Code:
    for (i=1; i<6; i++) {
      document.getElementById("specificButton0" + i).onmouseover = driveMenu;
    }
    You can then get the value of i by parsing this.id - the other parameters passed to driveMenu are all the same so I'm sure you could integrate them into the function somehow.

  5. #5
    SitePoint Guru
    Join Date
    Mar 2004
    Location
    Earth
    Posts
    406
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    What raffles said: you can't use the i value inside the methods, because it will be the same value for all of them - the residual value that remains after iteration. Your better bet is to extract the value from the element ID within driveMenu

  6. #6
    SitePoint Guru Chroniclemaster1's Avatar
    Join Date
    Jun 2007
    Location
    San Diego, CA
    Posts
    784
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    ummm... yes... I meant for (i=1; i<6; i++), thanks to everyone for the correction.

    The for statement takes a var keyword? I haven't seen that syntax before.


    Quote Originally Posted by brothercake View Post
    What raffles said: you can't use the i value inside the methods, because it will be the same value for all of them - the residual value that remains after iteration. Your better bet is to extract the value from the element ID within driveMenu
    Ewwww.... OK, that would explain a couple of my results, the last menu was certainly the buggiest.

    It sounds like part of my problem is prejudice from my .NET background. I once had to build a calculator interface in a VB class. I'm not even sure if this was correct, but we were told not to loop the button event handlers and simply call the text property (0-9). We created 10 separate event handlers for each button.

    What I'm hearing is that in Javascript at least , there's nothing fundamentally separate about the event handlers. And you can insert them in loops and conditionals just fine. I was worried that I was barking up the wrong tree entirely.
    Whatever you can do or dream you can, begin it.
    Boldness has genius, power and magic in it. Begin it now.

    Chroniclemaster1, Founder of Earth Chronicle
    A Growing History of our Planet, by our Planet, for our Planet.

  7. #7
    I meant that to happen silver trophybronze trophy Raffles's Avatar
    Join Date
    Sep 2005
    Location
    Tanzania
    Posts
    4,662
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    In the for statement, the first part is simply the declaration of a variable that you are going to use as the iteration marker. So if it hasn't been declared before in the same scope or in some higher scope, then it needs declaring, otherwise it will become a global variable, which could cause problems. I suggest you read up on global and local variables in javascript, and scope and closures if you feel inclined.

    Regarding what you did with .NET, adding an event handler 10 separate times in a hard-coded way and doing it 10 times in a loop should not make a difference, at least with javascript. I don't even know what .NET looks like.

    The problem with putting event handlers in loops is if there are a lot, you can create serious memory leak issues in IE if you aren't careful. Doing what I suggested should not cause IE to leak memory. I'd recommend a read on that too (this is a nice introduction to the topic), though I must admit I don't know the ins and outs of IE's memory leaking too well.

  8. #8
    SitePoint Guru
    Join Date
    Mar 2004
    Location
    Earth
    Posts
    406
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    pfft ... memory leaks are IE's problem And when - when - have you actually had a real user complain about problems due to excess memory useage?

  9. #9
    I meant that to happen silver trophybronze trophy Raffles's Avatar
    Join Date
    Sep 2005
    Location
    Tanzania
    Posts
    4,662
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Nevar! But I got a bit concerned recently because of all that stuff I've been reading about leaks so I've been trying to avoid them now, even though I generally don't really care about an inferior user experience with IE - it deserves it!

  10. #10
    SitePoint Guru
    Join Date
    Mar 2004
    Location
    Earth
    Posts
    406
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Well I wouldn't say that - but the amount of memory that has to leak before it becomes a real, noticeable problem is pretty extreme. It's far more trivial an issue than the press it gets would suggest.

  11. #11
    SitePoint Guru Chroniclemaster1's Avatar
    Join Date
    Jun 2007
    Location
    San Diego, CA
    Posts
    784
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    phew! ok, I finally got everything worked out. I would have finished it sooner, but I've been working on an IE keyboard navigation bug too and that turned into a big project.

    I should have the pages posted tonight. I'll throw up a link to them when they go live.
    Whatever you can do or dream you can, begin it.
    Boldness has genius, power and magic in it. Begin it now.

    Chroniclemaster1, Founder of Earth Chronicle
    A Growing History of our Planet, by our Planet, for our Planet.

  12. #12
    SitePoint Guru Chroniclemaster1's Avatar
    Join Date
    Jun 2007
    Location
    San Diego, CA
    Posts
    784
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    OK, no guarantees that this doesn't leak something awful. So far as I can tell, I don't have anything self-referencing, but all the articles said they're nasty to find, so who knows.

    Anyway, these event handlers trigger the menus on my navbars beautifully, so it's obviously possible. I used three nested loops to construct a pair of event handlers for each element, one to turn the menu on when you mouse over, one to turn the menu off when you mouse out. Here's a brief outline or you can check out the page that describes the work at...

    http://beta.earthchronicle.com/ECBet...dHandlers.aspx

    Code:
    // cycles through each element of the navbar, constructs menu on and off events for each one
    function navbarEvents() {
    
       var arrNavbars = new Array("specific", "siteWide");
       var arrNavElement = new Array("Button", "Menu");
       var intNumberOfNavElements = 5;
    
       // this loop works with arrNavbars to affect both navbars
       for (var i = 0; i <= 1; i++) {
          // this loop works with arrNavElement to affect Buttons and Menus
          for (var j = 0; j <= 1; j++) {
             // this loop cyles through the element numbers
             for (var k = 1; k <= intNumberOfNavElements; k++) {
    
                k = twoDigitString(k);
    
                //compile the navbar ids: each consists of a prefix indicating the navbar, the name (Button or Menu) of the element, and the numeric identifier
                var strNavElementId = arrNavbars[i] + arrNavElement[j] + k;
    
                //setting the events to drive the menus
                document.getElementById(strNavElementId).onmouseover = MenuOn;
                document.getElementById(strNavElementId).onmouseout = MenuOff;
             }
          }
       }
    }
    Then I had to rewrite my menu functions. Using this.id in two functions turned out to be quite workable, or at least better than what I had before. Thanks Raffles, that was a good call.

    Code:
    function MenuOn() {
    
       // take the id of the calling element and use it to construct the id of the menu to turn off
       var myElement = this.id;
       var myId = myElement.substring(myElement.length - 2, myElement.length);
       var myNavbar = myElement.substring(0, 8);
       var myMenu = myNavbar + "Menu" + myId;
    
       // turn the menu on
       document.getElementById(myMenu).style.display="block";
    }
    Shockingly the MenuOff function is identical except it sets the display to "none".
    Whatever you can do or dream you can, begin it.
    Boldness has genius, power and magic in it. Begin it now.

    Chroniclemaster1, Founder of Earth Chronicle
    A Growing History of our Planet, by our Planet, for our Planet.


Bookmarks

Posting Permissions

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