ComputerWolf / SlickNav

Responsive Mobile Menu Plugin for jQuery
MIT License
939 stars 314 forks source link

possible for one parent item to be open instead of all parent items? #16

Open nataliehman opened 10 years ago

nataliehman commented 10 years ago

Hi, I just started to use this and got it working as expected but is it possible to have the menu display one parent item open at a time?

I don't want users having to tap other parent items in order to view other menu items especially when the menu can get really long on the mobile device.

Thanks for the awesome plugin anyhow :)

RawHatred commented 10 years ago

I was trying to find a solution for this too. :confused:

cwellsx commented 10 years ago

I wrote a function named slicknavOpened which I install using the open classback:

$(document).ready(function(){
    $('#menu').slicknav({
        open: function(trigger) { slicknavOpened(trigger); }
    });
});

The function is as follows:

function slicknavOpened(trigger) {
    var $trigger = $(trigger[0]);
    if ($trigger.hasClass('slicknav_btn')) {
        // this is the top-level menu/list opening.
        // we only want to trap lower-level/sublists.
        return;
    }
    // trigger is an <a> anchor contained in a <li>
    var $liParent = $trigger.parent();
    // parent <li> is contained inside a <ul>
    var $ulParent = $liParent.parent();
    // loop through all children of parent <ul>
    // i.e. all siblings of this <li>
    $ulParent.children().each(function () {
        var $child = $(this);
        if ($child.is($liParent)) {
            // this child is self, not is sibling
            return;
        }
        if ($child.hasClass('slicknav_collapsed')) {
            // this child is already collapsed
            return;
        }
        if (!$child.hasClass('slicknav_open')) {
            // could throw an exception here: this shouldn't happen
            // because I expect li to have class either slicknav_collapsed or slicknav_open
            return;
        }
        // found a sibling <li> which is already open.
        // expect that its first child is an anchor item.
        var $anchor = $child.children().first();
        if (!$anchor.hasClass('slicknav_item')) {
            return;
        }
        // close the sibling by emulating a click on its anchor.
        $anchor.click();
    });
}

When it opens a parent, this function closes any other parent that's already open.

I hope this is a solution to your need.

Let me know if you see any problems with or improvements to my solution.

RawHatred commented 10 years ago

I just tested your function and it works great on both desktop and touch platforms cwellsx. Awesome! Thank you. :smiley::thumbsup: I will let you know if I notice any problems later. :loudspeaker:

ComputerWolf commented 10 years ago

@cwellsx, thanks for the awesome solution. I would like to get this option added eventually, but in the meantime this seems to work!

iamcarloseperez commented 10 years ago

Awesome.

JoshHarrington commented 10 years ago

@ComputerWolf Really impressed with how easy slicknav is to get working, cheers for all the hard work! @cwellsx thanks so much for the solution, massive help :+1:

Rahu18 commented 9 years ago

@cwellsx Thank You So Much for the solution, i was searching for this solution for very long time, Thank you for your hard work.

design2dev commented 9 years ago

this isnt working on the latest release. kind of annoying for long menus..renders it useless really.

nouredine commented 9 years ago

replace "open" callback with beforeOpen

baroche commented 8 years ago

Thanks for the code, however I could not get this to work with the current version. I pasted the code at the end of jquery.slicknav.js

ghost commented 8 years ago

I can confirm that 'beforeOpen' works with latest release.

Example...

$('header .main-menu ul#menu-header').slicknav({
                              beforeOpen : function(trigger) { slicknavOpened(trigger); },
                              'duplicate': true, 
                              'prependTo': '.main-menu-container', 
                              'closedSymbol': String.fromCharCode('0xf105'),
                              'openedSymbol' : String.fromCharCode('0xf107'),
});

(I got fontawesome working for the parent symbols too 😄 )

digitalideaz commented 8 years ago

Can somebody please tell me how to implement solution provided by cwellsx That mean where to write the function and where to call it?

MGANDRAOS commented 7 years ago

beforeOpen is a must in the latest release.

Thanks a lot , saved my a**.