clickMenu

Description:
A clickable dropdown menu with (theoretically unlimited) submenus made out of an an unordered list. It’s behaviour is like an application menu (click to open, click to close, stays open even after hovering elsewhere).

Demo

Files: (last update: 2007-09-06 - v 0.1.6)

Usage:

<script type="text/javascript">$(document).ready(function()
{
	$('#list').clickMenu();
});
</script>

<ul id="list">
	<li>Item one
		<ul>
			<li>Subitem one</li>
			<li>Subitem two</li>
		</ul>
	</li>
	<li>Item two</li>
</ul>

More Examples:

<script type="text/javascript">
$(document).ready(function()
{
    $.fn.clickMenu.setDefaults({arrowSrc:'arrow_right.gif', onClick: function(){/*do something*/}});
    $('selector1').clickMenu(); /* use default values */
    $('selector2').clickMenu({arrowSrc:''}); /* dont use an arrow for submenus */
    $('selector3').clickMenu({subDelay: 1000, mainDelay: 500}); /* slow menu */
});
</script>

Available options:

  • onClick - function - callback function triggered when a list item is clicked - returning false will stop the default action of the clicked element
  • arrowSrc - string - url of the image to be used as an arrow indicating a submenu (e.g. “images/somearrow.jpg” or an empty string if you don’t want an arrow)
  • mainDelay - string or number - the time to wait before starting the fadein after hovering over a main menu item (”slow”, “normal” or “fast” or the time in milliseconds - e.g. 1000)
  • subDelay - string or number - the time to wait before starting the fadein after hovering submenu item (”slow”, “normal” or “fast” or the time in milliseconds - e.g. 1000)

Changelog:

  • v 0.1.6 - 2007-09-06
    • fix: having a link in the top-level menu would not open the menu but call the link instead
  • v 0.1.5 - 2007-07-07
    • change/fix: menu opening/closing now through simple show() and hide() calls - before fadeIn and fadeOut were used for which extra functions to stop a already running animation were created -> they were buggy (not working with the interface plugin in jquery1.1.2 and not working with jquery1.1.3 at all) and now removed
    • change: removed option: fadeTime
    • change: now using the bgiframe plugin for adding iframes in ie6 when available
  • v 0.1.4 - 2007-03-20
    • fix: the default options were overwritten by the context related options
    • fix: hiding a submenu all hover- and click-events were unbound, even the ones not defined in this plugin - unbinding should work now
  • v 0.1.3 - 2007-03-13
    • fix: some display problems ie had when no width was set on the submenu, so on ie the width for each submenu will be explicitely set
    • fix: the fix to the ie-width-problem is a fix to the “ie does not support css min-width stuff” problem too which displayed some submenus too narrow (it looked just not right)
    • fix: some bugs, when user the was too fast with the mouse
  • v 0.1.2 - 2007-03-11
    • change: made a lot changes in the traversing routines to speed things up (having better memory usage now as well)
    • change: added $.fn.clickMenu.setDefaults() for setting global defaults
    • fix: hoverbug when a main menu item had no submenu
    • fix: some bugs i found while rewriting most of the stuff
    • change: renamed file to jquery.clickmenu.js
  • v 0.1.1 - 2007-03-04
    • change: the width of the submenus is no longer fixed, the elements can use as much space as they need (fix for overflowing list elements)
    • change: the submenu-arrow is now an img, not the background-img of the list element - that allows better positioning, and background-changes on hover (you have to set the image through the arrowSrc option)
    • fix: clicking on a clickMenu while another was already open, didn’t close the open one
    • change: clicking on the open main menu item will close it
    • fix: on an open menu moving the mouse to a main menu item and moving it fastly elsewere hid the whole menu

Known problems:

  • not working without javascript turned on (yet)
  • haven one menu open and hovering over a main menu item of another menu, which is lying directly under the open menu, the open menu will get overdrawn by the item below (ie only)
  • on a menu with many sublevels, the response gets slower on each level when starting at level 5 or 6 (firefox only - see the demo)

The plugin was successfully tested on Firefox 2, Opera 9.21, IE 6 and IE 7.

64 Responses to “clickMenu”

  1. 1. When a user traverses a menu, how do I get the full traversed path?
    2. I am using FF on Fedora 5. The menu works until I get to item 2/…/happen when it takes seconds to respond. The next levels take even longer.

  2. peter,
    1. dou you want the information when a user hovers over an item or only when he clicks on something? and what kind of information do you want - a string (”main menu/level one/level two/im here”)? could you give an example, please?
    2. I have that too. the firebug profiler says that everything is as fast as always. I guess something is taking all the time before the script gets the mouseover-information. I’ll better add that to the known problems list.

  3. Sorry but downlods… don’t work ! (dead links)

  4. Damn, I knew I forgot something..
    Thanks for telling me, it should work now.

  5. Is it, or will it at some point in time be possible to disable items in a menu?

    This would be very helpful.

    Looks great so far, but I really need the disabled item part.

  6. Frank,

    yes, you can disable items.
    I’ve updated the demo page. The “Stylish menu” has disabled items now. They have the CSS class “disabled” set which makes them look disabled. In the onClick-function I make sure nothing happens when they get clicked.

  7. Very nice plugin but I had problems to get it running together with interface.js
    My temporary solution is to comment out the body of your function changeFX.
    Why do we need changeFX at all?

  8. I’ll look into that.
    The changeFX function makes it possible to stop running animations. That’s why I needed it. I’ll probaby have that removed in the next version going back to basic show/hide animations.

  9. Great stuff. But the menu shadow doesn’t work in IE, am I missing something? Also under Firefox, the separator is sticking out … maybe I screwed up something totally.

    FY

  10. In IE 6 and below the shadow is not working (I don’t know about IE 7) as IE doesn’t support .PNG images without hacks.

    On which page is the seperator sticking out? On the demo page?

  11. OK, how about the mouse out event for menus. After so long the menu goes away?

  12. you did a awesome plugin, thank you.
    btw, have any plan to support safari ?

  13. Hi there, this plugin is cool and I am using this as a flyout navigation menu, but I wonder is it possible to replace the click binding on first level’s with hover binding, so that the flyout menu will show when mouse-over the naviagtion buttons

  14. I’ll see if I can add support for the hover in and out events.

    I haven’t tested the plugins in safari yet, but I will!

  15. nice plugin!

    one thing i noticed: when you click on a parent item it closes the menu, but in a real application menu it doesn’t do that.

    Keep up the good work! :)

  16. here’s a pastie of my relevant code: http://pastie.caboo.se/76300

    I’m receiving an error saying line 63 jquery-menu.js variable h is not defined. going to line 63 says nothing about variable h.
    has anyone else encountered this issue?

    tried in both jQuery 1.1.2 and 1.1.3

  17. rick: you can use the onClick-callback-function having it close the menu only when you want :)

    eric: the current version (v0.1.4) doesn’t work with jquery 1.1.3. I unfortunately have had no time to work on this for the past weeks but I’m planning to fix it this weekend.

  18. ok tnx.

  19. alright, I’ve removed some of the unnecessary stuff fixing the bug with jquery 1.1.3 and reducing the filesize a little bit. it should be working fine again.

  20. it would be incredibly useful if you could add a addClickMenu() function to ANY item, even if it is not the menu itself. So basically you could turn any icon of class “xyz” into a popupmenu by calling $(”.xyz”).addClickMenu(”#menu_id”) without having to define the menu hierarchy each time under each xyz-icon. I have a list of 50+ items, each of which should need the same popup menu

  21. jeroen: something like this should already do the trick:

    $(’.xyz’).append($(’#menu_id’).clone().removeAttr(’id’)).clickMenu()

    Please tell me if this is working for you.

  22. I think I’m looking for the same thing jeroen is looking for, but your code doesn’t quite accomplish it. An example of what I’d like to be able to do can be found at: http://developer.yahoo.com/yui/examples/button/btn_example07.html

    Any chance your code could be enhanced to support this type of menu structure?

  23. Sorry for the slow response Travis,

    do you mean creating a menu from a select-box?

  24. Honestly, I don’t really care if it’s a select box or not, what I want is the visual effect that is displayed on that page, but using valid XHTML 1.0. I have images (look like buttons, several side-by-side) that should act like “menus”, but they are each independent menus. I think using unordered lists probably makes more sense (easier CSS styling). Your plugin is already close to what I need, but I need the button img to be the “trigger”, and then the UL should just display below the button when clicked.

    I’ve put up a demo of what I’m currently doing at: http://www.garethphipps.com/buttonmenu/

    I’d like to get away from the script I’m currently using because it’s a bit buggy and VERY large. I’d love to utilize jquery to perform this action.

  25. yeah, the yui buttonmenu is sweet. I’ll take a look into adding some of the functionallity into my plugin.

    playing a little with the stylesheets, I’ll got a menu, which almost looks alike (using your button) http://p.sohei.org/stuff/jquery/clickmenu/demo/demotestbutton.html

  26. Yeah, that’s pretty close (I actually like yours better with the shadow!). But the biggest problem I would have is that I can’t get multiple buttons side-by-side horizontally. Basically I’m building a sudo menubar using these buttons. So they absolutely have to be side-by-side. I tried just making the UL tags display: inline, but that didn’t work.

  27. I wonder if you guys did any more work on the button menu idea? I was playing around today with this method of creating stylish buttons: http://www.monc.se/kitchen/59/scalable-css-buttons-using-png-and-background-colors. If you combined the jquery script on that page with ClickMenu you could create a hybrid that does everything YUI does.

  28. I don’t like doing it, but a client requested that some of the menus link to outside websites in a new window. I added this to the top of your code for the re-write of the a tags onclick behavior:


    onClick: function(){
    $(this).find('>a').each(function(){
    if ( this.href )
    {
    if (this.target == "blank")
    {
    window.open(this.href);
    }
    else
    {
    window.location = this.href;
    }
    }
    });
    },

    Tested in FF2 and IE6

    May need to put adjust for frames if I come across that too. /shrug

    Nice plugin.

  29. Owen: I started writing a new menu plugin, which should be more flexible. I just haven’t had enough time lately to work on it. Hopefully that will change soon.

    CA Russel: thanks for your addition!

  30. I’m curious why your menu package does not really use jQuery selectors for much of the node traversal, but instead the functions getOneChild, getAllChilds, etc. Did you find that the jQuery selectors were too slow?

  31. Could you please include all necessary files as even when I save the demo page with all included files it will not run properly.

    Its a nice plugin and exactly what I need.
    Thx

  32. Very nice plugin but I had problems to get it running together with interface.js
    My temporary solution is to comment out the body of your function changeFX.
    Why do we need changeFX at all?

  33. CJ: yes, the jQuery selectors were way too slow back then - maybe thats not the case anymore. i haven’t tested this yet.

    NccWarp9: there you go.

    Wasiq: the changeFX function was removed already. please update to the current version.

  34. I am having 2 difficulties integrating your menu into my site:

    1. On fire fox, the submenu won’t go past my main center page div (try clicking NJ History, and notice how the sub menu’s wrap. This won;’t happen in IE)

    2. In IE 6 (maybe 7) ther is a white border around the sub menu’s and a thick border to the right. If you click on NJ Comedy Scene you wil see a mini scroll bar on the border to the right. I want to get rid of these borders and such and have had no luck editing the CSS.

    (BTW I changed the trigger state from onClick to onHover, so it’s a hover menu now. Could you add code so i could simply pass this in at teh initilization of your class.

    Any help would be extremely helpful. The site is under development, so you would have to add
    207.58.143.208 http://www.so-jersey.com
    to your host file

  35. Dan,
    1. please try adding a “white-space:nowrap” css-rule to “.clickMenu li main.li” or use  
    2. thats probably the shadow which ie fails to display. adding “background-color: black” to “ul.innerBox” should to the trick

    I was puzzled by the onHover at first ;)
    that’s really nice!

  36. Can someone show me or point me in the direction of adding elements to a menu dynamically?

  37. Adding li-elements to the lists should work, but it’s not really supported (adding submenus won’t work at all). Sorry.
    I’m planning to add support for adding elements/menus dynamically, though, when I get the time to rewrite the plugin.

  38. In my case the menu items (unstructured) popup shortly when loading the page, maybe because my menu is extensive. How can I prevent that and show the menu as it should straightaway?

  39. mark, there is no build-in way to do this.
    but you could try something like this:
    add a class with display:none to your list and after loading the menu you just display it.
    eg.
    CSS: ul.hidemenu{ display:none }
    HTML: <ul class=”hidemenu”>…your menu..</ul>
    JS (after the .clickMenu() part): $(’ul.hidemenu’).show();

  40. Would it be better, performance wise, to put the menu (etc.) in JS. Gets cached better that way.

  41. I’m working on a complete rewrite of the menu plugin, that won’t need the html markup. But with the clickmenu plugin you’ll have to stick to the unordered lists for now.

  42. In your re-write, you should still allow HTML markup to “prototype” the menu or else the plugin will become useless on most applications. Web crawlers and bots do not crawl JS, and I am sure that people who use your menu care about their site being indexed by Google.

  43. Yep, I’m planning on supporting both ways.

  44. Is there a way to follow an url link on an item with children?

  45. Yes, as long it’s not the root item something like this schould work:

    <ul>
    	<li>root item
    		<ul>
    			<li>item 1</li>
    			<li><a href="somesite" rel="nofollow">item 2</a>
    				<ul><li>subitem</li></ul>
    			</li>
    			<li>item 3</li>
    		</ul>
    	</li>
    </ul
    

    so clicking on item 2 should follow the link.

  46. Is there any way I could split the behavior of a top-level menu item so that clicking on the anchor text will take me to a url, but clicking on the item’s arrow will drop down the menu? Something similar to the main navigation buttons on Facebook or Digg or Flickr.

  47. No, not really, sorry.
    Maybe you could make a menu out of every of the items arrows, but that wouldn’t be very nice and smooth.

  48. […] anyone interested, the new jQuery plugin being used is called clickMenu.  Below is two images of the new iteration of Neptune as it stands in the default skin.  […]

  49. Great plugin - thank-you! I’ve tested it in IE6, IE7 and FF2 on Windows, FF2 on Linux, and Safari3 on Mac. One question: when I control-click on a menu item in FF2 (in Windows & Linux), it doesn’t open the URL in a new tab. Oddly enough, when I control-click on a menu item in IE7 it does open the URL in a new tab. (First time I’ve ever gotten a preferred behavior from IE.) Any suggestions on how to fix this?

  50. Is there any way to make it onMouseOver instead of onClick? Any help is appreciated! Thanks!

  51. Scott: right now I’m working on a new menu plugin, which will support open-on-hover. I’ll try to port this feature into the clickMenu.

    Dallan: no, I don’t know a way to open an url into a new tab. Though, it’s possible to open links in a new window on ctrl-click, which again some browsers will open in a new tab instead!

    I’ve changed the onClick function (by CA Russell) a little bit:

    onClick:function(e){
    	$(this).find('>a').each(function(){
    		if ( this.href )
    		{
    			if (this.target == "blank" || e.ctrlKey )
    			{
    				window.open(this.href);
    			}
    			else
    			{
    				window.location = this.href;
    			}
    		}
    	});
    }});
    

    hope this helps,
    roman

  52. Scott: there is another way around to make it work with onmouseover instead of onclick,

    1. Replace $(liElems[j]).click(mainClick); -> $(liElems[j]).mouseover(mainHover); on line 473
    2. Replace mainClick function on line 303 with the following mainHover function :

    		var mainHover = function()
    		{
    			hoverIn(this, settings.mainDelay);
    			shown = true;
    			$(document).bind('mousedown', checkMouse);
    
    			return false;
    		}
    

    that’s it.

  53. Love the click menu. Have a problem with spidering of the items by bots. I get visitors on pages where they do not belong (considering the search query in Google)

  54. Jenna, can you give me more information about this, please? How do you use the plugin exactly? This seems like a problem with your access rights. Maybe I could take a look at your page?

  55. The menu contains resorts for the webcam pages. Googlebot eg sees on the Zermatt livecam page also all other resorts. Someone might end up via Google on the Zermatt webcam page searching for Saalbach. Before they would end up on the Saalbach webcam page.

  56. Well, I don’t know much about SEO, so I can’t even guess why the Zermatt page is ranking higher than the Saalbach page when your’e searching for Saalbach.

    Google is probably only seeing the resort list, so the plugin shouldn’t be at fault. Maybe fetching the list through an ajaxcall on page-load and then feeding it to the plugin could help. But I don’t really think that this is the problem. Getting deeper into the topic of SEO would maybe be more helpful.

    Sorry if I’m of no real help!

  57. For those who want to try out my new menu plugin, you can get it here. (it’s non-stable though!)

  58. I’ve found some error in using your plug-in: it happens, when someone has moved out mouse from submenu and then opened this parent “main” menu again. Submenu DIV doesn’t hide when i’m using jQuery v1.2.2, but excellent works using v1.1.4.

    http://fil.klarnet.ru/jQuery/test_jQeury_114.html - right working with DIV
    http://fil.klarnet.ru/jQuery/test_jQeury_122.html - doesn’t hide DIV

    This error has been detected only in Internet Explorer browser.

    There is screenshot of this error: http://fil.klarnet.ru/jQuery/error.gif

  59. Thanks for reporting this, filzone.
    I’ll try to fix that!

  60. Hi Roman,

    Sorry for not getting back earlier on this. The fix to open the link in a new window if the control key is pressed doesn’t work quite right, because it makes the newly-opened tab the active tab. Normally given the default settings in firefox and IE7, when you control-click on a link it opens the link in a new tab, but the *current* tab remains the active tab.

    I’ve done a little research on this, and there doesn’t appear to be a way to specify in javascript to open a link in a new tab but keep the current tab as the active tab in firefox. At least IE7 (but not firefox) exhibits the correct behavior using the old OnClick handler that you had, where you just set the window.location to this.href, so it’s probably best to put it back the way you had it originally.

    Thanks again for a *great* plugin!

  61. Roman,
    My menu would sometimes stay open after I clicked an entry. I fixed this by changing all of the ‘click’ event to ‘mousedown’ events.
    Unless you see a downside, I would suggest making this change for your next release.
    Thanks,
    -Dave

  62. I too found same error as filzone - it happens with both jQuery v1.2.2 and 1.1.4. I am using IE7. I have tried my best to fix it - but no joy. any pointers for me??

    its a great plugin and does exactly what we need - pity about this bug!

    Kind Regards

  63. Hello,

    I would like to insert a array into the callback function when clicking on a menu item. Is there a way to achieve this without the need to modify the plugin code directly?

    Thanks in advance.

    squig

  64. RE: engage February 20th, 2008 at 6:02 pm

    Hi RW

    I have been playing with this and a change I made has solved the problem for me — I hope it may be of use to others

    Kind regards
    Catherine

    $.fn.clickMenu = function(options)
    {
    var shown = false;
    var theCallback = ”;
    var liOffset = ( ($.browser.msie) ? 4 : 2 );

    var settings = $.extend({}, defaults, options);

    var hideDIV = function(div, delay)
    {
    //a timer running to show the div?
    if ( div.timer && !div.isVisible )
    {
    clearTimeout(div.timer);
    }
    else if (div.timer)
    {
    return; //hide-timer already running
    }
    if ( div.isVisible )
    {
    div.timer = setTimeout(function()
    {
    //remove events
    $(getAllChilds(getOneChild(div, ‘UL’), ‘LI’)).unbind(’mouseover’, liHoverIn).unbind(’mouseout’, liHoverOut).unbind(’click’, settings.onClick);
    //hide it
    // hack to this plugin 21/02/08
    // if the div is an outerbox then delay its hiding
    // if this isn’t done, this piece of javascript has not enough
    // time to run and hide
    if (div.className==”outerbox”) {
    $(div).hide(500,theCallback);
    }
    else {
    $(div).hide();
    }
    div.isVisible = false;
    div.timer = null;
    }, delay);
    }
    };

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>
Syntax Highlighting: You can use [js] .. [/js] and [html] .. [/html] for posting code snippets.