0

I've created a click menu in WordPress and so far so good, except clicking outside the menu to close it. The below code works, but there has got to be a better way.

Question: If you have any tips on improving this so that I don't have to call each menu class individually and can use a shared class, please let me know:

   /*
    * Close .sub-menu when clicked outside menu
    *
    */

    $( document ).bind( 'click touchend', 'html', function( e ) {

        var a    = e.target;

        if ( $( a ).parents( '.nav-primary' ).length === 0 ) {

            $( '.nav-primary li' ).removeClass( 'sub-menu-open' );
            $( '.nav-primary li .sub-menu-toggle' ).attr( 'aria-expanded', 'false' ).attr( 'aria-pressed', 'false' );
            $( '.nav-primary li' ).children( '.sub-menu-toggle' ).children( '.screen-reader-text' ).text( visionary_objectL10n.openChildMenu );

        } // .nav-primary

        if ( $( a ).parents( '.nav-tertiary' ).length === 0 ) {

            $( '.nav-tertiary li' ).removeClass( 'sub-menu-open' );
            $( '.nav-tertiary li .sub-menu-toggle' ).attr( 'aria-expanded', 'false' ).attr( 'aria-pressed', 'false' );
            $( '.nav-tertiary li' ).children( '.sub-menu-toggle' ).children( '.screen-reader-text' ).text( visionary_objectL10n.openChildMenu );

        } // nav-tertiary       

        if ( $( a ).parents( '.nav-procedures' ).length === 0 ) {

            $( '.nav-procedures li' ).removeClass( 'sub-menu-open' );
            $( '.nav-procedures li .sub-menu-toggle' ).attr( 'aria-expanded', 'false' ).attr( 'aria-pressed', 'false' );
            $( '.nav-procedures li' ).children( '.sub-menu-toggle' ).children( '.screen-reader-text' ).text( visionary_objectL10n.openChildMenu );

        } // nav-procedures     

        $( document ).unbind( 'click touchend', 'html' );

} );

What I've tried.

This doesn't work. When I click outside it works but when I click another menu the sub-menus I was just clicking on stays open. I am clearly just guessing, I have no clue.

$( document ).bind( 'click touchend', 'html', function(e) {

        var target    = e.target,
            parents = $( target ).parents( 'nav' );

        if ( $( parents ).length === 0  ) {

            $( target ).parents().find( 'li' ).removeClass( 'sub-menu-open' );

        } 

        $( document ).unbind( 'click touchend', 'html' );

} );         

See my answer below to see what I ended up doing.

Christina
  • 34,296
  • 17
  • 83
  • 119

2 Answers2

1

you are just close to the end :-)

part 1: you can simply add a nav class to all your nav-"whatever" elements and search for clicked elements parents only having .nav class

part 2: in .nav elements click function remove the class sub-menu-open from any li and then add it to only clicked li or .nav (I'm not sure because i do not know your html but seems like you do know what to do and how to do it just got a bit confused)

Amin Setayeshfar
  • 468
  • 6
  • 23
  • It's getting there. Since WordPress menus have a toggle and a link and in my js if there is only a # for the link I open the sub-menu but when there is not a hash, this link does nothing and the button opens the children, I'm having difficulty isolating. I will come back later, after I deal with other stuff. – Christina Feb 27 '17 at 14:46
  • Well I never did figure it out and resorted back to the one that works for the time being. I may hire this out if it really bugs me. – Christina Mar 01 '17 at 20:23
0

The accepted answer pointed me in one direction, which helped solve this question. However due to the complexity of the way I had toggled the attributes and L10n text, I was struggling. So I ended up doing this short and efficient solution which I learned from this answer on SO. All the menus have a shared class 'nav-bar-menu':

$( document ).bind( 'click touch', 'body', function( event ) {

    var $dropdowns = $( '.nav-bar-menu li' );

    $dropdowns.not( $dropdowns.has( event.target ) ).removeClass( 'sub-menu-open' );
    $dropdowns.not( $dropdowns.has( event.target ) ).children( '.sub-menu-toggle' ).attr( 'aria-expanded', 'false' ).attr( 'aria-pressed', 'false' );
    $dropdowns.not( $dropdowns.has( event.target ) ).children( '.sub-menu-toggle' ).children( '.screen-reader-text' ).text( visionary_objectL10n.openChildMenu );

   $( document ).unbind( 'click touch', 'body' );

} );
Community
  • 1
  • 1
Christina
  • 34,296
  • 17
  • 83
  • 119