Page 1 of 2 12 LastLast
Results 1 to 10 of 17

Thread: Dropdown menu w. keyboard access

  1. #1
    Join Date
    Dec 2005
    Posts
    39
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Dropdown menu w. keyboard access

    Greetings, Its been awhile since I've posted here, but I've come seeking help again.

    With my limited knowledge of javascript I've been working on a script to make a dropdown menu accessible using the keyboard. I've gone as far as I can and realized I'm in over my head. I don't know where to go from here to keep the appropriate submenus open when the anchor in the parent level loses focus. Simply replacing the className again onblur obviosly won't work.

    Any help is much appreciated, thank you.
    Code:
    function menuHide() {
     var a = document.getElementById("nav").getElementsByTagName("a");
     for (var x = 0; x < a.length; x++) {
     var li = a[x].parentNode;
     while (li.nodeName != 'LI') li = li.parentNode;
      if (li.childNodes.length > 1) {
       for (var y = 0; y < li.childNodes.length; y++) {
        if (li.childNodes[y].nodeName == 'UL') li.className += " js-hide";
       }
      }
      li.onmouseover = function() {
       if(/\bjs-hide\b/.test(this.className)) this.className = this.className.replace("js-hide", "js-show");
      }
      li.onmouseout = function() {
       if(/\bjs-show\b/.test(this.className)) this.className = this.className.replace("js-show", "js-hide");
      }
      a[x].onfocus = function() {
       var thisLi = this.parentNode;
       while (thisLi.nodeName != 'LI') thisLi = thisLi.parentNode;
        if(/\bjs-hide\b/.test(thisLi.className)) thisLi.className = thisLi.className.replace("js-hide", "js-show");
       }
    //  a[x].onblur = function() {}
     }
    }
    window.onload = menuHide;
    Last edited by billyboy; 10-20-2008 at 09:02 PM.

  2. #2
    Join Date
    Jul 2006
    Posts
    497
    Thanks
    8
    Thanked 70 Times in 70 Posts

    Default

    Please post the menus' HTML source as well so we can test them together.
    -- Chris
    informal JavaScript student of Douglas Crockford
    I like wikis - a lot.

  3. #3
    Join Date
    Dec 2005
    Posts
    39
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default

    Test page with the full code is uploaded here

  4. #4
    Join Date
    Jul 2006
    Posts
    497
    Thanks
    8
    Thanked 70 Times in 70 Posts

    Default

    What browser are you testing in? In Firefox, the menus never hide while I navigate via Ctrl. In fact, I wish a menu would hide when I navigate to a separate menu.

    I think you'll need to record which menu item has focus and make sure only its ancestors are expanded.
    -- Chris
    informal JavaScript student of Douglas Crockford
    I like wikis - a lot.

  5. #5
    Join Date
    Dec 2005
    Posts
    39
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default

    the menus never hide while I navigate via Ctrl.
    Exactly. Thats what I need help with. How to keep appropriate submenus open while hiding the others

  6. #6
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default

    Just a note on concept. Using the keyboard to activate javascript will almost always run afoul of user defined and browser default hot keys. Since you have no control or knowledge as regards the former, and the later vary with each browser, and potentially with each browser version, it (using hot keys in javascript) is generally a fruitless approach.

    The mechanism(s) for detecting keystrokes in javascript are best applied in getting your code to integrate users' normal expectations for non-javascript code into your script. For example, if you have an onmouseover event on a link, it will not be activated onfocus unless you detect that the user is intending to do that and have that action also activate the event. This can be accomplished (among other ways) in part by detecting actions on the part of the user that constitute navigating links on a page via the keyboard.

    But to attempt to take wholesale control over keystrokes for the exclusive use of a script will almost always prove unworkable due to conflicts with some reserved action for those keystrokes in at least enough situations as to render the code very browser specific at best.
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  7. #7
    Join Date
    Dec 2005
    Posts
    39
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default

    A user expects anchors to have focus as they use tab in FF or IE, Ctrl + arrow keys in Opera, etc. as those are the defaults in those browsers. No hot keys are being set, nothing is being overridden in the code. Events are fired when focus is set on an anchor, however that happens, whatever key or key combination is used for that, whether its the default setting or a user defined preference.

  8. #8
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default

    I see, my mistake. Please accept my apologies. I'll have a look at the code. However, I notice that the menu doesn't even react intuitively onmouseover/out, at least not all the time. Once you get that working, one would think that making onmouseover = onfocus, and onmouseout = onblur (as it were) could do the trick.
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  9. #9
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default

    OK, after looking at and testing the code further, I see that it does respond well onmouseover/out in FF and IE 7, but not in Opera. I also see that the mouse events are tied to the li elements, and that the pseudo :hover class style is used. The pseudo :hover class will not work in IE 6, except on linked anchors and their children. However, to get this working with focus, it would probably be best to skip any dynamic action on the part of style and to set things up so that only events (mouse and otherwise) on the anchor links themselves do anything. Once you get that worked out for the mouse, porting it to onfocus and onblur should be easy.
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  10. #10
    Join Date
    Dec 2005
    Posts
    39
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default

    I made an edit to the CSS to fix a problem in IE6 and forgot to check Opera again afterward. Its fixed now.

    Applying :hover and the class generated by javascript for IE6 to the li is based on the code for son of suckerfish. If I change that part so mouseover on the anchor is what does anything I'm going to up against the same wall with that as what I am now with onfocus on the anchor.
    Last edited by billyboy; 10-21-2008 at 06:35 AM.

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
  •