1

I have a function

function giveTheseEqualHeight ( selector )
{
     // selector: CSS selector of elements on the page to be forced to have the same height

     var these = $(selector);
     if (these.length < 2) return; 
     these.height('auto');
     var maxHeight = these.first().height();
     these.each(function(){
        var thisHeight = $(this).height();
        if (thisHeight > maxHeight) maxHeight = thisHeight;                
     });
     these.height(maxHeight);
}

which is very self explanatory.

Example use case:

giveTheseEqualHeight('.service-column h3'); 

would make all h3 elements that are descendants of elements of class service-column have equal height by heightening the ones that are smaller than the one with the most height.

The problem is that the loop

             these.each(function(){
                var thisHeight = $(this).height();
                if (thisHeight > maxHeight) maxHeight = thisHeight;                
             });

doesn't need to execute its body on the first iteration -- such amounts to useless operations. Instead of these.each, I want to start with the 2nd item. Is this possible?

Barmar
  • 741,623
  • 53
  • 500
  • 612

3 Answers3

1

jQuery has slice. Slice from second element (index 1). If the end is omitted, it slices until the end.

these.slice(1).each(...);
Joseph
  • 117,725
  • 30
  • 181
  • 234
  • Does `slice` use references of the set of returned objects, or does it make copies of them? –  Sep 02 '15 at 21:14
  • @WebDevonPIPatAmazon.com The contents are the same references. It's just the wrapping jQuery object that's different. – Joseph Sep 02 '15 at 21:16
1

You can avoid calculating height of the first element if you get array of heights and then take the max with native Math.max:

function giveTheseEqualHeight(selector) {
    var these = $(selector);
    if (these.length < 2) return;
    these.height('auto');

    var maxHeight = Math.max.apply(null, these.map(function(el) {
        return $(this).height();
    }));
    these.height(maxHeight);
}

Here is a demo of it:

function giveTheseEqualHeight(selector) {
    var these = $(selector);
    if (these.length < 2) return;
    these.height('auto');
    
    var maxHeight = Math.max.apply(null, these.map(function(el) {
     return $(this).height();
    }));
    these.height(maxHeight);
}

giveTheseEqualHeight('div')
div {display: inline-block;background: #EEE; vertical-align: top;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div>Lorem</div>
<div>Test <br>rest</div>
<div>Test <br> and rest <br>on the <br>west</div>
dfsq
  • 191,768
  • 25
  • 236
  • 258
  • Are you sure that's faster? Getting an array of the heights involves iterating through the elements. So that's an extra iteration through an object of length `N`. –  Sep 02 '15 at 21:22
  • If you are really concerned with performance then don't use jQuery each in the first place, go with native loop and compare like you are doing now. – dfsq Sep 02 '15 at 21:24
  • 1
    @WebDevonPIPatAmazon.com if you're really concerned about speed, http://stackoverflow.com/a/13440842/1770430 has a solution that's purported to be 3X faster than Math.max.apply(). – Nzall Sep 02 '15 at 21:28
0

Use the greater-than selector to select all elements who's index is greater than the number provided.

afrin216
  • 2,295
  • 1
  • 14
  • 17