0

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.

Daniel Hallqvist
  • 822
  • 5
  • 15
  • If you can find out what function adds the new list elements you could hook your own handler to that event without adjusting other code segments. – Simon Sep 10 '12 at 08:33
  • Simon: Yea, I wish... Sadly I can't control that since li's can get added from external code in the project, which I have no control over from my side :( – Daniel Hallqvist Sep 10 '12 at 08:37
  • That's what I'm talking about: you do not need control over the other code, since it's JS you can read it on your side don't you? So you can find out what event handler adds new list elements and you can write your own handler and hook it on the same event :) – Simon Sep 10 '12 at 09:14

1 Answers1

1

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);​
xiaohao
  • 272
  • 1
  • 7