5
\$\begingroup\$

I've created code for a menu system that can show / hide menus and submenus. Now I wonder if the structure of the code is good enough or if you find something that can be done better?

var initExpanders = function () {
    "use strict";

    function lsTest(){
        var test = 'localstoragetest';
        try {
            localStorage.setItem(test, test);
            localStorage.removeItem(test);
            return true;
        } catch(e) {
            return false;
        }
    }

    var IS_OPEN = 'open',
        localStorageisAvailable = lsTest();

    /**
     * Add the small arrows indicating an expander.
     *
     * @returns {string} to be inserted in document.
     */
    function expandButton() {
        return '<span class="indicator icon-down-open"></span>' +
            '<span class="indicator icon-up-open"></span>';
    }

    /**
     * Toggle state and of the expander.
     *
     * @param event The click event
     * @param expanderNode
     * @param bodyId
     */
    function toggleExpander(expanderNode, bodyId, from_history) {
        var bodyNode = expanderNode.find(bodyId);
        var speed = 200; //'fast'
        if (from_history == true) {
            //No sliding time if it was remembered from history
            speed = 0;
        }
        if (expanderNode.hasClass(IS_OPEN)){
            $.each(bodyNode, function() {
                $(this).slideUp(speed, function () {
                    expanderNode.removeClass(IS_OPEN);
                    storeOrRemoveHistory(expanderNode);

                });

            });
        } else {
            $.each(bodyNode, function() {
                $(this).slideDown(speed, function () {
                    expanderNode.addClass(IS_OPEN);
                    storeOrRemoveHistory(expanderNode);
                    if ($(this).is('tr')) {
                        $(this).css('display', 'table-row');
                    }

                });

            });

        }

    }

    /**
     * Init localstorage history if localstorage available, trigger expand if any found
     * Saved by index of expanders at url.
     * @param node
     * @param titleNode
     * @param index
     */
    function initLocalStorageHistory(node, titleNode, index) {
        if(localStorageisAvailable) {
            $(node).attr('data-position', index);
            var dataPosition = window.location.href + index;

            if (localStorage.getItem(dataPosition)) {
                //Don't open anything if referrer is pren
                if($.urlParam('ref') != 'pren') {
                    $(titleNode).trigger('click', true);
                }
            }
        }
    }
    $.urlParam = function(name){
        var results = new RegExp('[\?&]' + name + '=([^&#]*)').exec(window.location.href);
        if (results != null) {
            return results[1] || 0;
        } else return null;
    }
    /**
     *
     * Save state of expander to localstorage if available
     * @param expanderNode
     */
    function storeOrRemoveHistory(expanderNode) {
        if(localStorageisAvailable){
            var dataPosition = window.location.href + $(expanderNode).attr('data-position');

            if ($(expanderNode).hasClass(IS_OPEN)) {
                localStorage.setItem(dataPosition, 'open');
            } else {
                localStorage.removeItem(dataPosition);
            }
        }
    }


    /**
     * Enable all expanders.
     */
    $.each($('.expander'), function (i, node) {
        var titleNode = $(node).find('.expander-title:first');
        $(titleNode).append(expandButton());
        $(titleNode).click(function (event, from_history) {
            var clickTarget = $(event.currentTarget),
                expanderNode = clickTarget.closest('.expander'),
                from_history = from_history || false;
            if(window.location.href.indexOf("survey") > -1) {
                toggleExpander(expanderNode, '.expander-body', from_history);
            }
            else {
                toggleExpander(expanderNode, '.expander-body:first', from_history);
            }
        });
        initLocalStorageHistory(node, titleNode, i);
    });
}

$(document).ready(function () {
    "use strict";
    initExpanders();
});
\$\endgroup\$
1
\$\begingroup\$

I see a generic catch

catch(e)

If you make a spelling mistake, this will catch no method exception and always return false, very nasty and hidden bug. I suggest specifying exactly the expected exception.

\$\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.