Search code examples
javascriptjquerydelegatesslicknav

Slicknav and delegated click events


I'm rather new to coding and my understanding is limited. But I'm using Slicknav for mobile screen sizes, however according to the author of the plug in.

"SlickNav menu items are created Dynamically" so I need to use delegated click events or attach event handlers after SlickNav is created. My SlickNav post

I need some help with this. According to This, I tried making a delegated events.

Here is the original code which is a " direct" event handler (I think)

menuitem.eq(0).on('click', function(){
status = 1;
clearBox();
statusCheck();

});

BTW all my code is trying to do is 1. Clear out a Container which is a display window for content. And 2. Append the correct content to that window based on the menu item that is clicked.

Here is my attempt at a delegated event:

$('#navMenu').on('click',menuitem.eq(0), function(){
status = 1;
clearBox();
statusCheck();

});

Also tried replacing .on() with .delegate(), no dice.

For completeness ill including the functions that the cick events are calling

function clearBox(){
$("#display_box").children().fadeOut(1000).appendTo(".holding");


};

function statusCheck(){
    if (status == 1){

    displaycontent.eq(0).fadeIn(1000).appendTo("#display_box");
    displaycontent.eq(0).removeClass("hide");
    $("#display_box").animate({scrollTop:0},500);
    } else{}

    if (status == 2){

    displaycontent.eq(25).fadeIn(1000).appendTo("#display_box");
    displaycontent.eq(25).removeClass("hide");
    $("#display_box").animate({scrollTop:0},500);
    } else{}  
    // Etc Etc Etc

Edit: Provided HTML for the Menu

<div class ="menu_wrap"> 
<nav id = "navMenu">
<ul class ="clearfix menu">
 <li>General
    <ul class="subMenu1">
        <li class ="menu_item">Introduction</li>
        <li class ="menu_item"> What you need</li>
        <li class ="menu_item">House Rules</li>
        <li class ="menu_item">Running the Game</li>
        <li class ="menu_item">Survival</li>
        <li class ="menu_item">Encounters</li>

    </ul>
   </li>
    <li>The World 
        <ul class ="subMenu1">
            <li class ="menu_item">Nol</li>
            <li class ="menu_item">Wol</li>
            <li class ="menu_item">Sol</li>
            <li class ="menu_item">Eol</li>
        </ul>   
    </li>
    <li><a href="index_maps.html">Locations and Maps</a></li>
<li>Races and Cultures
    <ul class ="subMenu1">
            <li> <a class="allow_default" href="index_npcs.html"   target="blank">NPC Creatures</a></li>
            <li class ="menu_item"> Voran Kingdom</li>
            <li class ="menu_item">Doval Empire</li>
            <li class ="menu_item">Salatai Sultanate</li>
            <li class ="menu_item">Gamoran Republic</li>
            <li class ="menu_item">Elandel</li>
            <li class ="menu_item">Kingdom of Night</li>
            <li class ="menu_item">Halflings</li>
            <li class ="menu_item">Aiur' Dun</li>
            <li class ="menu_item">Half-Elves</li>
            <li class ="menu_item">Half-Orcs</li>
            <li class ="menu_item">Dryads</li>

    </ul>
</li>
<li> Organizations
    <ul class ="subMenu1">
            <li class="menu_item">Information</li>
            <li class ="menu_item">The Green Wardens</li>
            <li class ="menu_item">The Temple of Light</li>
            <li class ="menu_item">The Black Hand</li>
            <li class ="menu_item">The Stone Priests</li>
            <li class ="menu_item">The Golden Company</li>
            <li class ="menu_item">The Dread Guards</li>
            </ul>

</li>

<li class ="menu_item">Character Creation
    <ul class ="subMenu1">
        <li class ="menu_item"> <a class="allow_default"      href="index_personality_test.html" target="blank">Creation Test</a></li>
    </ul>   
</li>


</ul>
</nav>
</div>

Solution

  • Try something like this:

    <nav id="navMenu">
    <ul class="clearfix menu">
     <li>General
        <ul class="subMenu1">
            <li class="menu_item" data-item="intro">Introduction</li>
            <li class="menu_item" data-item="requirements">What you need</li>
            <li class="menu_item" data-item="rules">House Rules</li>
    ...
    

    And this for the JavaScript:

    $('#navMenu, .slicknav_menu').on('click', '.menu_item', function() {
        clearBox();
    
        switch($(this).attr('data-item')) {
            case 'intro': {
                // Do something here.
                break;
            }
            case 'requirements': {
                // Do something here.
                break;
            }
            case 'rules': {
                // Do something here.
                break;
            }
            // More cases...
        }
    });
    

    It appears the cloned menu created by SlickNav is placed directly under the <body> element, so you cannot call .on() only on your #navMenu element. You could call it on the body element, but the code above calls it on both the #navMenu and .slicknav_menu elements. The <ul> element generated by SlickNav has the slicknav_menu class on it.

    As written, the code above has to be called after you call .slicknav() since it requires the cloned menu exist when it is called. Otherwise, you would have to change to $('body').on(....

    As for the rest, the selector '.menu_item' identifies all the menu item elements, so the click-event handler will execute for all of them. But each menu item element has a different value for the data-item attribute. That way you can do something different for each one.

    jsfiddle