SitePoint Sponsor

User Tag List

Results 1 to 12 of 12
  1. #1
    SitePoint Zealot Hieronymus's Avatar
    Join Date
    Nov 2004
    Location
    Nederland, Eindhoven
    Posts
    145
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    need to identify more then one object

    Hi There,

    I have a nice looking pulldown menu on my site and it uses mainly CSS to make it work. But to make it work in Win/IE there is a little bit of Javascript.

    I use a MemberLogin. I will use this so I can make specific administration pages, outside the CMS etomite. The menuscript generates a two deep menu (thus one submenu) In the admin page (which doesn't do anything..yet) there is another submenu. The problem is that Win/IE6 won't display it. The damn thing works fine in firefox. As allready figured out in this topic in the CSS forum that is because Win/IE needs the script to identify the right <ul>-tag and that you can only use it once.

    ow yeah, to see the extra menu's you need to login site->login
    user: Test1
    pwd: testing

    Is there another way to do this so that you theoretically have an infinite number of menu's?

    here is the code, it's included in the main document.

    Code:
    // JavaScript Document
    
    startList = function() {
    if (document.all&&document.getElementById) {
    navRoot = document.getElementById("nav");
    for (i=0; i<navRoot.childNodes.length; i++) {
    node = navRoot.childNodes[i];
    if (node.nodeName=="LI") {
    node.onmouseover=function() {
    this.className+=" over";
      }
      node.onmouseout=function() {
      this.className=this.className.replace(" over", "");
       }
       }
      }
     }
    }
    window.onload=startList;
    What good are one-liners if they don't
    fit.

  2. #2
    SitePoint Member
    Join Date
    Oct 2004
    Location
    Bangalore
    Posts
    20
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You need a recursive function (a function which calls iteslf) to add mouseOver and mouseOut events.

    The plan is to get a node under navRoot,
    if the node is LI, attach mouseOver and mouseOut events or
    if the node is UL, call the function again.

    Here is the modified code:

    HTML Code:
    function startList(navRoot) {
    	if (document.all&&document.getElementById) {
    		for (var i=0; i<navRoot.childNodes.length; i++) {
    			var node = navRoot.childNodes[i];
    			if (node.nodeName=="LI") {
    				node.onmouseover=function() {
    					this.className+=" over";
    				}
    				node.onmouseout=function() {
    					this.className=this.className.replace(" over", "");
    				}
    			}
    
    			if(node.hasChildNodes()) startList(node);
    		}
    	}
    }
    
    window.onload=function() { startList(document.getElementById("nav")) };
    But the real problem starts now. The CSS you have can handle only one level, to handle multiple level sub-menus, you have to add more selectors.

    I have attached a sample file, (original from alistapart.com) that can handle upto 3 levels. [Change the extension from .txt to .html]

    Pls let me know if you come up with a better way of handling multple selectors.

    - Kiran Makam
    Attached Files Attached Files

  3. #3
    SitePoint Zealot Hieronymus's Avatar
    Join Date
    Nov 2004
    Location
    Nederland, Eindhoven
    Posts
    145
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Exclamation

    Thanx for pointing out that the code on my site can't handle menu's more then 2 deep. Somehow I never noticed that.

    The real problem lies in this: I don't need more than 2 deep menu's (would be nice though) but I need more than one menu on a page. As you can see as you login to my site.

    I've added the source as it would look like if it was made by the CMS (don't worry, Etomite doesn't make such ugly code ) If you load it in, lets say, firefox. It works fine, but it doesn't in Win/IE and that's where I need the javascript code for.

    I've tried you're example but I couldn't get it to work.

    I also added the background, so you can make it look pretty
    Attached Images Attached Images
    Attached Files Attached Files
    What good are one-liners if they don't
    fit.

  4. #4
    SitePoint Member
    Join Date
    Oct 2004
    Location
    Bangalore
    Posts
    20
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You have named both UL tags as 'nav', instead I have named it as nav1 and nav2 and below is the modified script

    HTML Code:
    <script type="text/javascript">
    function startList(navId) {
    	if (document.all&&document.getElementById) {
    		var navRoot = document.getElementById(navId);
    		for (i=0; i<navRoot.childNodes.length; i++) {
    			node = navRoot.childNodes[i];
    			if (node.nodeName=="LI") {
    				node.onmouseover=function() {
    					this.className+=" over";
    				}
    				node.onmouseout=function() {
    					this.className=this.className.replace(" over", "");
    				}
    			}
    		}
    	}
    }
    
    
    window.onload= function(){
    	startList('nav1');
    	startList('nav2');
    }
    </script>
    Tested on ie6, both menus work fine.

    - Kiran Makam
    Attached Files Attached Files
    Last edited by kiranmn; Jan 5, 2005 at 06:36. Reason: Forgot to attach the modified menu.txt

  5. #5
    SitePoint Zealot Hieronymus's Avatar
    Join Date
    Nov 2004
    Location
    Nederland, Eindhoven
    Posts
    145
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Yeah Thanx, that is the kind of sollution I'm looking for, at least I hope.

    The script is static. I can just put it in my header. Now, as I pointed out, I need to generate an arbitrary number of menu's. So one question: Is it possible to make such a functioncal from within the HTML document?

    Something like this:

    HTML Code:
    <head>
    <script>
    place script here
    + one functioncall window.onload= function(){
    	startList('nav1');}
    because that one will always be visible
    </script>
    </head>
    <body>
    
    *content*
    
    here the PHP-code places a menu but the output of that script starts with
    <script>
    window.onload= function(){
    	startList('admin');}
    </script>
    <div class="menuHeader">Admin</div>
    <div class="navigation">*the menu-thing*</div>
    </body>
    Well it would be nuts if something like this wouldn't work. But I ask you anyway.
    What good are one-liners if they don't
    fit.

  6. #6
    SitePoint Zealot Hieronymus's Avatar
    Join Date
    Nov 2004
    Location
    Nederland, Eindhoven
    Posts
    145
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Damn it, I just tested the idea above and it doesn't work.

    If you try to seperate the functioncall like this:
    HTML Code:
    <script type="text/javascript">
    window.onload= function(){
    	startList('nav1');
    }
    </script>
    
    <script type="text/javascript">
    window.onload= function(){
    	startList('nav2');
    }
    </script>
    Only the last call gets executed. (I tried with switching them)

    If you put them in one functioncall, they both work. So I can think of two sollutions
    1) use something else then window.onload to activate the script.
    2) try to collect all the id's and them execute them in one functioncall. I realy don't know if such a thing is possible.
    What good are one-liners if they don't
    fit.

  7. #7
    SitePoint Zealot
    Join Date
    Dec 2004
    Location
    Finland
    Posts
    103
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You can add more than one onload-function.
    Code:
    if (window.addEventListener) { // W3C DOM
     window.addEventListener("load", func, false); }
    else if (document.all&&window.attachEvent) { // IE
     window.attachEvent("onload", func); 
    }

  8. #8
    SitePoint Zealot Hieronymus's Avatar
    Join Date
    Nov 2004
    Location
    Nederland, Eindhoven
    Posts
    145
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Looks cool to me, but how do I use it?

    I really don't know much about Javascripting and nothing about DOM
    What good are one-liners if they don't
    fit.

  9. #9
    SitePoint Zealot
    Join Date
    Dec 2004
    Location
    Finland
    Posts
    103
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You could add such JavaScript for each menu (replacing "func" with "nav1", "nav2", ...) but I think it's better to use something like this for onload:
    Code:
    function initAll() {
     for (var i=1; ; i++) {
      var id="nav"+i;
      if (document.getElementById(id)) {
       startList(id);
      }
      else break;
     }
    }

  10. #10
    SitePoint Zealot Hieronymus's Avatar
    Join Date
    Nov 2004
    Location
    Nederland, Eindhoven
    Posts
    145
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Well I still don't understand your first sollution

    If I understand your last one correct it looks at the document and checks if there is a menu by the name 'nav1' and then activates it, then 'nav2' and so on.

    I'm affraid that will not be possible because different users that login, get to see different menu's. So it will not be 1 trough 5 but more like menu 1,2,4 or 1,3,5 and so on.

    I've tried a few things implement both sollutions, but I can't get it done. So I need a little more help here.
    What good are one-liners if they don't
    fit.

  11. #11
    SitePoint Zealot
    Join Date
    Dec 2004
    Location
    Finland
    Posts
    103
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    My first solution was like you trying to add multiple onload events - the same code needs to be added multiple times, with different argument each time - replace "func" with startList("nav1"), startList("nav2") etc. However, you are better off with either of these:

    This one activates all menus div1 ... div10 it finds, even if there are some menus missing in between.
    Code:
    function initAll() {
     for (var i=1; i<=10 ; i++) {
      var id="nav"+i;
      if (document.getElementById(id)) {
       startList(id);
      }
     }
    }
    This one activates named menus. You can add as many as you like.
    Code:
    function initAll() {
     var menus=String("nav1 nav3 nav5").split(' ');
     for (var i=0; i<menus.length; i++) {
      var id=menus[i];
      if (document.getElementById(id)) {
       startList(id);
      }
     }
    }

  12. #12
    SitePoint Zealot Hieronymus's Avatar
    Join Date
    Nov 2004
    Location
    Nederland, Eindhoven
    Posts
    145
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanx man, I really like the last one. Within Etomite I can now use the menu title for it's id.

    very nice. Adding a menu to the template now involves two steps: Add it in the body and add it's title in array.

    very nice. I'm done here.
    What good are one-liners if they don't
    fit.


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
  •