0
\$\begingroup\$

I have created a script that handles the responsive liabilities of my HTML menu. The menu will have a variable amount of <li class="menu-item">, resulting in a variable total width. I have 3 functions.

This function is responsible for looping through each li element and calculating the greatest width of the set of elements.

function resize_menu() {

    var maxWidth = -1;

    $(".menu-item").each(function() {
        maxWidth = maxWidth > $(this).width() ? maxWidth : $(this).width();
    });

    $(".menu-item").each(function() {
        $(this).width(maxWidth);
    }); 
}

This function is responsible for displaying the mobile menu, and hiding the standard menu.

function mobile_menu() {
    $("#mobile-menu").css("display", "block");

    $(".menu-primary-menu-container").css("display", "none");
}

This function is responsible for showing the standard menu, and hiding the mobile menu, invert of the above.

function show_menu() {
    $("#mobile-menu").css("display", "none");

    $(".menu-primary-menu-container").css("display", "initial");
}

Now to execute functions above, I have created instances in which they need to be fired.

$( window ).load(function() {
    //declare variables
    var resizeTimer;
    var maxWidth = -1;
    var count = $(".menu-item").length;

    // Loop menu items, and retrieve greatest width, to be multiplied by count
    $(".menu-item").each(function() {
        maxWidth = maxWidth > $(this).width() ? maxWidth : $(this).width();
    });

    // Only resize li elements if screen width is greater than menu width
    if ($(window).width() > maxWidth * count) {
        resize_menu();  
    } else {
    // or else show the mobile menu
        mobile_menu();
    };

    // On a resize (delayed for performance)
    $(window).on('resize', function(e) {
        clearTimeout(resizeTimer);
        resizeTimer = setTimeout(function() {
            // again, if window is less than menu, show mobile 
            if ($(window).width() < maxWidth * count) {
                mobile_menu();
            } else {
            // or else, show regular menu
            // Note: resize, incase screen was loaded smaller than menu 
                resize_menu();
                show_menu();
            };  
        }, 50);
    });

    // if the mobile menu icon is clicked, show menu
    $("#mobile-menu").click(function() {
        show_menu();
    });
});

This code does work, however there are some performance issues. When I resize the window, some times the hiding of the regular menu, and showing of the mobile is delayed, caused probably by the timeout I set, is it worth getting rid of? Also, I know this code is wet, lots of repetition. I could use advice on that. Finally, how can I store my selectors in variables and use them throughout the script?

\$\endgroup\$
  • 1
    \$\begingroup\$ What does the standard menu look like? What does the mobile menu look like? Are the list items arranged vertically or horizontally? \$\endgroup\$ – Spike Oct 31 '15 at 17:40
1
\$\begingroup\$

Suggestion: The Math.max method is shorter than ternary operator:

maxWidth = Math.max(maxWidth, $(this).width());
maxWidth = maxWidth > $(this).width() ? maxWidth : $(this).width();
\$\endgroup\$

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.