21

I think this is a pretty straightforward problem but...

var outerHeight = $('.profile').outerHeight();
$("#total-height").text(outerHeight + 'px');

Right now the var outerHeight gives me the outerHeight of only the first element with the class .profile.

How can I get the sum of the outerHeights of all elements with the class .profile?

Bennett
  • 959
  • 4
  • 12
  • 18
  • 3
    You've asked a few question here at SO but you've never accepted an answer. You should accept an answer (check mark next to the numbers) if one of the answers helped you. – Ruan Mendes Jun 23 '12 at 01:09

9 Answers9

36

Loop through each matching element and add up the outerheights:

var outerHeight = 0;
$('.profile').each(function() {
  outerHeight += $(this).outerHeight();
});
$("#total-height").text(outerHeight + 'px');
Flash
  • 15,945
  • 13
  • 70
  • 98
16

Here's the straight forward solution. Just loop through the elements of the jQuery object summing up the outerHeight()s.

var total = 0;
$('.profile').each(function(){
    total += $(this).outerHeight();
});
// total is good here

The important thing is that all jQuery getters only return the value of the first element in the jQuery set but you can add them yourself.

And here's a roundabout but cool way of doing it http://jsfiddle.net/mendesjuan/bKtAn/6/

// You can use a jQuery object as the `this` param in `Array.prototype` functions
var totalHeight = Array.prototype.reduce.call($('span'), function(a,b){
   // The first param is either the default value (passed into reduce)
   // or the result of the last call of this reducing function
   return a + $(b).outerHeight();
}, 0);

Which could be generalized as a reduce and made into a plugin like: http://jsfiddle.net/mendesjuan/bKtAn/9/

(function( $ ) {
    $.fn.reduce = function(cb, init) {  
      return Array.prototype.reduce.call(this, function(a,b){
            return cb(a, b);
      }, init);  
    }
})(jQuery);

const total = $('span').reduce(
   (accumulator, current) => accumulator + $(current).height(),
   0
);
console.log({total});

I think I went a bit overboard, sorry, I got excited, but these code snippets teach you a lot about JS and even a bit of jQuery

Ruan Mendes
  • 90,375
  • 31
  • 153
  • 217
6

$("selector") is already a collection. Access directly the .outerHeight() or any other method like .height()

var total = 0;
$("div").outerHeight(function(i, v){
   total += v;
});

alert( total ); // Just to test

var total = 0;

$("div").outerHeight(function(i, v){ total += v; });

alert( total );
div{background:#eee; margin:3px;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div style="height:100px;">100px</div>
<div>just lots of breaklines :)<br><br><br><br></div>
<div style="height:200px;">200px</div>
Roko C. Buljan
  • 196,159
  • 39
  • 305
  • 313
3
var total = 0;
$('.profile').each(function() {
     total += $(this).outerHeight();
});

$("#total-height").text(total + 'px');
Rey Gonzales
  • 836
  • 1
  • 8
  • 17
2

jQuery functions that don't return a jQuery object operate only on the first member of a list.

If you want to iterate over all .profile elements, you can use .each()

var totalHeight = 0;
$('.profile').each(function(i, e) {
    totalHeight += $(e).outerHeight();
});
Interrobang
  • 16,984
  • 3
  • 55
  • 63
  • The params passed to `$('selector').each` are not the same as the params passed to `$.each`. There's no `e` parameter, `this` refers to the HTML element – Ruan Mendes Jun 23 '12 at 00:10
  • You are completely wrong. http://api.jquery.com/each/ even lists the signature as `.each( function(index, Element) )` You can test to see that `e` exists if you like. (`this` is available as well) – Interrobang Jun 23 '12 at 01:56
  • My bad, I assumed it from the description on http://api.jquery.com/jQuery.each/ "The $.each() function is not the same as $(selector).each(), " They are not the same but they both do pass the element as the second parameter. The only difference is that $(selector).each() sets `this` to the same thing as the second parameter. – Ruan Mendes Jun 23 '12 at 02:15
2

Try this:

var outerHeightTotal = 0;
$('.profile').each(function(){
  outerHeightTotal += $(this).outerHeight();
});
marteljn
  • 6,446
  • 3
  • 30
  • 43
2

You can use get an array of the native elements and reduce to get the sum.

This might be cleaner because it's one line without the need to declare a variable in advance.

const height = $('div').get().reduce((prev, curr) => prev + curr.offsetHeight, 0);
console.log(height);
.child1 {
  height: 30px;
  background: red;
}

.child2 {
  height: 50px;
  background: green;
}

.child3 {
  height: 10px;
  background: blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<div class="child1"></div>
<div class="child2"></div>
<div class="child3"></div>

This approach can be used without jQuery of course. The [...] thing is to convert NodeList to an array of elements)

const height = [...document.querySelectorAll('div')].reduce((prev, curr) => prev + curr.offsetHeight, 0);
console.log(height);
.child1 {
  height: 30px;
  background: red;
}

.child2 {
  height: 50px;
  background: green;
}

.child3 {
  height: 10px;
  background: blue;
}
<div class="child1"></div>
<div class="child2"></div>
<div class="child3"></div>
Mosh Feu
  • 28,354
  • 16
  • 88
  • 135
0

You can also be lazy as me and introduce a new jQuery function that will do all the work for you, like this:

(function($) {    
    $.fn.sumOfOuterHeights = function () {
        var sum = 0;
        $(this).each(function () {
            sum += $(this).outerHeight();
        });
        return sum;
    };
})(jQuery);

And then use it in your code wherever you like it:

var height = $('.a, .b, .c').sumOfOuterHeights();

For me it is also a little bit more readable and DRY if you use it often.

Mirous
  • 403
  • 7
  • 14
0

More modern option:

let height = 0
$('.profile').each((i, el) => height += $(el).outerHeight())
Rauli Rajande
  • 2,010
  • 1
  • 20
  • 24