1

I'm trying to increase a number on each iteration of a for loop, in jQuery (1.4.2), by the width of the previous element.

I've tried the following:

var
$lis = $('#bookmarks > li'),
liHeight = parseInt($lis.height()),
numLis = $lis.length;
console.log(numLis);

var totalLeft = '0';
console.log(totalLeft);

for (i=1; i<numLis; i++) {
    var leftOffset = $lis.eq(i-1).width();
    var leftTotal = leftOffset + leftTotal;


    console.log(leftOffset +"/"+ leftTotal);
}

The output from this section is:

11 (the length of the array)
0 (the initial value of 'totalLeft')
97/97
117/214
90/
115/NaN
101/NaN
138/NaN
93/NaN
96/NaN
102/NaN
80/NaN

I've tried using parseInt() around one, and both, variables in the var leftTotal = leftOffset + leftTotal; variable assignment, to no avail. I've also tried using jQuery's each(), with the exact same result. Which is unsurprising, since I assigned the values in almost exactly the same way...

There are two questions here:

  1. Why is leftTotal not-a-number (NaN)?
  2. How can I add the new value of leftOffset to the previous-iteration's value of leftOffset?

The console log should read something like:

11
0
97/97
117/214
90/304
115/419
101/520
138/658
93/751
96/847
102/949
80/1029


Edited in response to @KennyTM:

Console.log output is now (more promising):

11
0
97 "/" "970"
117 "/" "117970"
90 "/" "90117970"
115 "/" "11590117970"
101 "/" "10111590117970"
138 "/" "13810111590117970"
93 "/" "9313810111590117970"
96 "/" "969313810111590117970"
102 "/" "102969313810111590117970"
80 "/" "80102969313810111590117970"

With regards to @Tomalak: yeah, it was a typo. Sadly it was a typo in both my code here and in the real darn script. ...sigh... Thanks for the catch, though, that seems to have done a lot to help out.

...how embarrassing. =)

3
  • 2
    That you're not assigning to totalLeft is a typo? Commented Sep 25, 2010 at 8:25
  • @Tomalak, +1 for paying more attention to my jQuery than I was... =) Since that, and a sneaky parseInt() resolved my problem I'd be happy to accept your comment as an answer, if you'd care to post it as such? Commented Sep 25, 2010 at 8:33
  • Hm. Done. Obviously too late. Also you've accepted an answer that can't possibly work. Commented Sep 25, 2010 at 9:14

5 Answers 5

4

i'd try somethin like this:

var leftTotal = 0
$('#bookmarks > li').each( function(){ 
    leftTotal += parseInt(this.width());  // just to be sure its an int :) 
    console.log(this.width(); +"/"+ leftTotal);
});
Sign up to request clarification or add additional context in comments.

3 Comments

You can (should) use this.width instead of $(this).width().
@Tomalak: No, there is no width attribute for an li element.
@someGuy, I'm assuming that the first semi-colon in the console.log... line is a typo, or am I just not getting it?
1

It appears that you are not assigning to totalLeft in your code.

Also, I think your code is way to complicated and has subtle errors. Here is a more compact and jQuery-style version.

var totalLeft = 0;

$('#bookmarks > li:gt(0)').prev().each(function () {
    totalLeft += $(this).width();
});

At least, this generates the same number as the code in your own answer.

Comments

1

It seems you are not keeping the last value for the next iteration. i.e - put " var leftTotal" out of the loop, so it will keep the value for the next iteration and you'll add to it.

Hope I got you right :)

1 Comment

I created the variable outside of the loop, but called it totalLeft. And then, for some reason, inside the loop called it leftTotal. It seems that was the crux of the problem. But +1 for the suggestion.
0
var totalLeft = 0;
console.log(totalLeft);

for (i=1; i<numLis; i++) {
    var leftOffset = $lis.eq(i-1).width();
    var leftTotal = parseInt(leftOffset,10) + totalLeft;


    console.log(leftOffset +"/"+ leftTotal);
}

Comments

0

The solution was, apparently, to pay a little more attention to variable names, and use a parseInt:

var
$lis = $('#bookmarks > li'),
liHeight = parseInt($lis.height()),
numLis = $lis.length;
console.log(numLis);

var leftTotal = '0';    // somehow, between creating this var and the loop I started calling it something else 'totalLeft', for no known reason.
console.log(leftTotal);

for (i=1; i<numLis; i++) {
    var leftOffset = $lis.eq(i-1).width();
    var leftTotal = leftOffset + parseInt(leftTotal);   // added the parseInt here to force it to be a number.      

    console.log(leftOffset, "/" , leftTotal);
}

Thanks to @Tomalak who caught my clinical blindness... =)

5 Comments

Why are you treating leftTotal as a string at all? Just initialise it to integer zero and you can drop the weird parseInt. height() and width() return plain integers, you should not need to parse anything. (Otherwise, always use parseInt(..., 10) to ensure you are not caught out by the infamous leading-zero-means-octal trap.)
someguy's solution is clearer than this. If it is also correct, you should op for that instead of this. Also you are missing var in for (i=1...) and you should move the declaration var leftTotal outside of the loop for clarity
@Justin, done. @Bob...honestly? I don't know, I think, at one point, console.log(variable) returned 38px, and I assumed that the 'px' portion would require the parseInt()...I think I just got ridiculously confused somewhere.
The return value of width() always is an int. The value of the CSS property might contain px, but you're not using that here. Then again, the value of the CSS property might also contain em or %, so that you would not get away with a ``parseInt()` anyway.
Yeah, it's css('width') that returns a width in CSS length format, with potentially a trailing unit like px. width() is always integer screen-pixels.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.