Search code examples
javascriptjqueryperformancesettimeoutzepto

Perfomance of timeout functions


I have a JS-problem where I have to check a horizontal ul for when the li's of that lists width has gone over a max-width, and then reduce the side-padding of those elements to make all li's fit.

The problem is that I can not fire an event when a li is added, simply because I can't control all the code that adds li's to the ul.

So my option has been to loop the check of the li's total width a few times a second, something like this:

function UpdateNavBar(initialX) { 
        var w = 0;
        var maxW = 100;
        var visibleLis = $(".navigationbar ul li.menuitem");
        $.each(visibleLis, function (i, e) {
            return w += $(e).width();
        });
        if (w >= maxW) {
            --xPadding;
            $(".navigationbar ul li.menuitem a").css({ "padding-left": xPadding, "padding-right": xPadding });

        }

        w = 0;
        setTimeout(UpdateNavBar, 100, initialX);
    }
    var xPadding = parseInt($(".navigationbar ul li.menuitem a").css("padding-left").replace("px", ""));
    UpdateNavBar(xPadding);​

My questions are: Is there any other obvious ways to achieve this that I'm missing? How will a function like this affect perfomance of a site, keeping in mind that it is meant to be ran on all kinds of devices?

Thanks a lot.


Solution

  • em, since you didn't know when a li is added, a loop of settimeout is a not a bad way.

    but you can make some optimization.

    settimeout will add a handler to the ui thread, so if the time the handler finish executing is short enough, it will result in a better perfomance.

    so, my choice is like above code, maybe you can do better

    var listLength; 
    function UpdateNavBar(initialX) { 
        var w = 0;
        var maxW = 100;
        var visibleLis = $(".navigationbar ul li.menuitem");
        //make a momorize and if no change happen, do nothing
        if(length === visibleLis.length){
            return false;
        }else{
            listLength = visibleLis.length;
        }
        $.each(visibleLis, function (i, e) {
            return w += $(e).width();
        });
        if (w >= maxW) {
            --xPadding;
            $(".navigationbar ul li.menuitem a").css({ "padding-left": xPadding, "padding-right": xPadding });
    
        }
    
        w = 0;
        setTimeout(UpdateNavBar, 100, initialX);
    }
    var xPadding = parseInt($(".navigationbar ul li.menuitem a").css("padding-left").replace("px", ""));
    UpdateNavBar(xPadding);​