4
\$\begingroup\$

I'm building a navigation that has a breadcrumb with drop down menus. I want the menus to open up when I click the open link, then there are many instances when the menu should close:

  • The link is clicked a second time, with the intention of closing the menu
  • When another menu is open, the first menu should close
  • When a menu is open, and anywhere outside the menu is clicked
  • When a menu item is clicked

I'm anticipating that I'll have many click events to handle, and many different types of menus, pop-ups and drop downs through the entire site, so I'm trying to handle that efficiently, thus the switch statement.

$().ready(function () {    
    //Click event mayhem!
    $('html').click(function (event) {
        event.stopPropagation();
        var target = $(event.target);
        switch (target.attr('class')) {
            case 'expandDropDown':
                handleBreadCrumbDropDownClick(target);
                break;
            case 'headlineTitle':
                event.preventDefault();
                handleAccordionItemClick(target);
                break;
            default:
                //Always close dropdown menus, unless they're specifically being opened
                toggleDropDown('.BC-DropDown-Open');
        }
    });
});

function handleBreadCrumbDropDownClick(target) {
    //Get the drop down list being targeted
    var dropDownList = '#' + target.attr('itemprop');
    //Offset of the expander link
    var offset = target.offset();
    if ($(dropDownList).hasClass('BC-DropDown-Open')) {
        //Dropdown is being closed with the expandDropDown link
        $(dropDownList)
                        .hide()
                        .toggleClass('BC-DropDown-Open');
    }
    else {
        //Dropdown is being opened with the expandDropDown link

        if ($('.BC-DropDown-Open').length > 0) {
            //Close existing drop down lists if any
            toggleDropDown('.BC-DropDown-Open');
        }
        //Open selected dropdown
        toggleDropDown(dropDownList, offset);
    }   
}
\$\endgroup\$
2
\$\begingroup\$

The switch statement isn't needed.

Just set a click function for each class.

$(document).ready(function ready () {    
    $('.expandDropDown').click( handleBreadCrumbDropDownClick );
    $('.headlineTitle').click( handleAccordionItemClick );
});

function handleBreadCrumbDropDownClick() {
    var target = $(this);
    var dropDownList = $('#' + target.attr('data-itemprop'));
    var offset = target.offset();
    if ( dropDownList.hasClass('BC-DropDown-Open') ) {
        dropDownList
          .hide()
          .toggleClass('BC-DropDown-Open');
    }  else {
        if ( $('.BC-DropDown-Open').length ) {
            toggleDropDown('.BC-DropDown-Open');
        }
        toggleDropDown(dropDownList, offset);
    }   
}
\$\endgroup\$
  • \$\begingroup\$ Thanks for the feedback, also, thanks for referencing the 'data-' attribute. I just barely heard of that and haven't seen a usage yet. \$\endgroup\$ – MrGrigg May 17 '11 at 13:03
  • \$\begingroup\$ While I like the cleaner look of your suggestion, without assigning a click to $('html') the menus will not close when clicking on other elements on the page. Do you have any suggestions? \$\endgroup\$ – MrGrigg May 17 '11 at 13:53
  • \$\begingroup\$ I'd need to see the html. But in short it's more manageable to bind to the individual elements than to listen to the whole page and try to sort it out afterwards. A $('html *:not(.expandDropDown, .headlineTitle)').click(defaultClick); would have the same effect, but it's still messy. \$\endgroup\$ – generalhenry May 17 '11 at 19:52
  • \$\begingroup\$ I definitely want to maintain manageability, especially since I don't think I'll be the one to finish this project. I'm trying to find the best solution for something that might end up being rather large. \$\endgroup\$ – MrGrigg May 20 '11 at 17:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.