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 12 of 12

Thread: DOM drop downs

  1. #1
    New Coder
    Join Date
    Mar 2004
    Posts
    78
    Thanks
    0
    Thanked 0 Times in 0 Posts

    DOM drop downs

    Ok, I just tried to make this post and got logged out when I hit preview, so this time around it's gonna be much shorter as my patience has run out.

    ...Over at gazingus.org there is a sweet little bit of code that uses the DOM to make dropdown menus.

    I have altered the code (see below) to make the menus appear on the first mousover instead of the onClick event.

    However, they never go away. I'm trying to figure out how make the last menu open disappear after a short delay. I've already tried this

    actuator.onmouseout=function(){

    if(currentMenu){
    setTimeout('currentMenu.style.visibility = "hidden";',2000);
    }
    }
    However, it doesn't work. The delayed code events pile up on each other if menus are continually moused over and out. (Say the user can't decide what menu they're looking for and runs the mouse left...then right...then left...)

    The result is that after the 2000ms the menus close instantly....

    any ideas?
    Cheers,
    Simon Dvorak
    Code:
    /*
     * menuDropdown.js - implements an dropdown menu based on a HTML list
     * Author: Dave Lindquist (http://www.gazingus.org)
     */
    
    var currentMenu = null;
    
    if (!document.getElementById)
        document.getElementById = function() { return null; }
    
    function initializeMenu(menuId, actuatorId,position) {
        var menu = document.getElementById(menuId);
        var actuator = document.getElementById(actuatorId);
    
        if (menu == null || actuator == null) return;
    
        if (window.opera) return; // I'm too tired
    
        actuator.onmouseover = function() {
            if (currentMenu == null) {
                 this.showMenu(position);
            }
    		else if(currentMenu) {
    			currentMenu.style.visibility = "hidden";
                this.showMenu(position);
    		}
    		return false;
        }
      
        actuator.onmouseout = function() {
    	if(currentMenu){
          setTimeout('currentMenu.style.visibility = "hidden";',2000);
    	  return false;}}
                
    
        actuator.showMenu = function(position) {
    		if (document.all){
            menu.style.left = this.offsetLeft + 80 - position + "px";
    		}
    		else {
    		menu.style.left = this.offsetLeft - position + "px";
    		}
            menu.style.top = this.offsetTop + this.offsetHeight + 2 + "px";
            menu.style.visibility = "visible";
            currentMenu = menu;
        }
    }
    Last edited by sidvorak; 03-30-2004 at 07:22 PM. Reason: wrong code

  • #2
    Senior Coder
    Join Date
    Feb 2004
    Posts
    1,206
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Well I didn't really look at your code, I just downloaded it myself and altered it the way I thought it should be.

    It seems to work. I've attached the menuDropdown.js

    Hope that helps,
    Sadiq.
    Attached Files Attached Files
    Last edited by sad69; 03-30-2004 at 07:56 PM.

  • #3
    New Coder
    Join Date
    Mar 2004
    Posts
    78
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Thanks for the effort. However, having the onmouseout function like that doesn't let you choose anything from the menus as they disappear as soon as the mouse leaves the activating button.

    That is one reason for needing a delay. I guess it should probably be a mouseout event on the menu instead of the button...

    Still stuck,
    Simon

  • #4
    Senior Coder
    Join Date
    Feb 2004
    Posts
    1,206
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Hehe, oops...

    Ok I'll work on it..

    Sadiq.

  • #5
    Senior Coder
    Join Date
    Feb 2004
    Posts
    1,206
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Wowzas! I think I've finally got it down.

    I think I ran into a similar situation as you (the actuator wasn't disappearing).

    My solution was to add another actuator after that one, and just keep it empty. I've attached the whole thing for you. Let me know how it works out for you and if you have any troubles.

    Sadiq.
    Attached Files Attached Files

  • #6
    New Coder
    Join Date
    Mar 2004
    Posts
    78
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Thanks sad69. Unfortunately, the menus still don't disappear if a user mouses out on a menu.

    I was able to get it to work by adding mouseover and mouseout events to the menus as well and tracking whether or not another mouseover event has happened. here is the code.

    Thanks again!
    Simon

    Code:
    var currentMenu = null;
    if (!document.getElementById)
        document.getElementById = function() { return null; }
    
    function initializeMenu(menuId, actuatorId,position) {
        var menu = document.getElementById(menuId);
        var actuator = document.getElementById(actuatorId);
        if (menu == null || actuator == null) return;
        if (window.opera) return; // I'm too tired
    
        actuator.onmouseover = function() {
            if (currentMenu == null) {
                this.showMenu(position);
            }
    		else if(currentMenu) {
    			currentMenu.style.visibility = "hidden";
                this.showMenu(position);
    		}
    		a=0;
    		return false;
        }
    	actuator.onmouseout = function() {
    		a=1;
    		setTimeout('if(a==1){currentMenu.style.visibility = "hidden"};',10000);
    	}
        menu.onmouseover = function(){
    		a=0;
    	}
    	menu.onmouseout = function() {
    		a=1;
    		setTimeout('if(a==1){currentMenu.style.visibility = "hidden"};',10000);
    	}
        actuator.showMenu = function(position) {
    		if (document.all){
    		menu.style.left = this.offsetLeft + 80 - position + "px";
    		}
    		else {
    		menu.style.left = this.offsetLeft - position + "px";
    		}
            menu.style.top = this.offsetTop + this.offsetHeight + 2 + "px";
            menu.style.visibility = "visible";
            currentMenu = menu;
        }
    }

  • #7
    Senior Coder
    Join Date
    Feb 2004
    Posts
    1,206
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Well as long as you got it working!

    That's odd that my code doesn't work for you, since it works for me. What browser are you using? I could only test mine on IE...

    Sadiq.

  • #8
    New Coder
    Join Date
    Mar 2004
    Posts
    78
    Thanks
    0
    Thanked 0 Times in 0 Posts
    I'm using IE6 and Firefox .08...

    The code you sent worked when I moused out over the activator but not when I ended by mousing out over one of the menu dropdowns...

    Cheers,
    Simon

  • #9
    Senior Coder
    Join Date
    Feb 2004
    Posts
    1,206
    Thanks
    0
    Thanked 0 Times in 0 Posts
    So when you mouse out of a drop down menu you want that drop down menu to disappear? I didn't know that.. but whatever, if you've got it working then bravo!

    Cheers,
    Sadiq.

  • #10
    Regular Coder
    Join Date
    Mar 2004
    Posts
    130
    Thanks
    0
    Thanked 0 Times in 0 Posts
    However, it doesn't work.
    ...
    The result is that after the 2000ms the menus close instantly...
    The menu should not be hidden in 2000ms if the user has activated the menu.

    Clear the timer.

    First you need a timer id.

    Code:
    actuator.timer = setTimeout("hideMenu("'+actuator.id + "')", 500);

    Then in your mouseover functions (one for menu and one for actuator), clear the timer:
    Code:
    clearTimeout(actuator.timer);

  • #11
    New to the CF scene
    Join Date
    Oct 2004
    Posts
    2
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Cool more changes that worked for me

    I think the timer is only a Window object...

    Code:
    var currentMenu = null;
    
    if (!document.getElementById)
        document.getElementById = function() { return null; }
    
    function initializeMenu(menuId, actuatorId) {
        var menu = document.getElementById(menuId);
        var actuator = document.getElementById(actuatorId);
    	var timer;
    	
        if (menu == null || actuator == null) return;
    	
    	actuator.onmouseover = function() {
    		window.clearTimeout(timer);
            if (currentMenu) {
                currentMenu.style.visibility = "hidden";
    			menu.style.left ="";
    			menu.style.top = "";
                this.showMenu();
            }
        }
    	
    	actuator.onmouseout = function() {
    		window.clearTimeout(timer);
            if (currentMenu != menu) {
    			menu.style.left ="";
    			menu.style.top = "";
                this.showMenu();
            }
        }
    	
    	menu.onmouseout = function() {
            if (currentMenu != null) {
    			timer = window.setTimeout('currentMenu.style.visibility = "hidden"',2000)
    		}
    		else {
    			window.clearTimeout(timer);
    		}
        }
    	
    	menu.onmouseover = function() {
       		window.clearTimeout(timer);
        }
    
    	actuator.showMenu = function() {
    		tmph = menu.offsetTop;
    		menu.style.left = this.offsetLeft + "px";
    		menu.style.top = tmph + (this.offsetTop + this.offsetHeight) + "px";
    		menu.style.visibility = "visible";
    		currentMenu = menu
    	}
    }

  • #12
    Senior Coder
    Join Date
    Jun 2002
    Location
    near Oswestry
    Posts
    4,508
    Thanks
    0
    Thanked 0 Times in 0 Posts
    You don't need a delay to acheive this...

    There's a method in IE (bear with me) called contains() which can be used to evaluate the relationship between two objects - it returns whether one contains the other. That's exactly what you need - examine the mouseout event to determine whether the menu tree contains it - if it does then do nothing, if it doesn't then send hide the menu.

    Okay that's IE only, but it's simple to prototype using this nifty code courtesy of jkd:
    Code:
    HTMLElement.prototype.contains = function(node) {
    	if (node == null)
    		return false;
    	if (node == this)
    		return true;
    	else
    		return this.contains(node.parentNode);
    }
    Now only mozilla supports HTMLElement prototyping, but since the script is object oriented that doesn't matter - you can prototype contains() as a method of the menu actuator itself:
    Code:
    actuator.contains = function(node)
    {
    	if (node == null) { return false; }
    	if (node == this) { return true; }
    	else { return this.contains(node.parentNode); }
    }
    Check this out to see it in action: http://www.brothercake.com/scripts/listmenu/
    Last edited by brothercake; 10-05-2004 at 02:57 AM.
    "Why bother with accessibility? ... Because deep down you know that the web is attractive to people who aren't exactly like you." - Joe Clark


  •  

    Posting Permissions

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