sambadave
sambadave

Reputation: 23

For loop not working as I would expect it to

Sorry for not being clearer here guys. Thanks for the quick responses.

I'm looking to use this snippet of js to equalise the heights on various divs. It only appears to work for for divs with class "jsEq-1" (shown in the red box in my snippet.

I'm also expecting the green and yellow boxes to equalise out in height... so all green boxes will be the same height and all yellow boxes will be the same height. So although the content in each box is a different length I want the containers to be equal heights and everything to line up.

The green boxes have a class of jsEq-2 and the yellow boxes have a class of jsEq3 but my script doesn't seem to work on divs with class of "jsEq-2" or "jsEq-3" "jsEq4" etc etc.

I'd like it to loop through any divs with class beginning with "jsEq-" and any number at the end but I just can't figure this out.

Thanks in advance for any tips.

$(window).load(function() {

    $.fn.extend({
        equalHeights: function(){
            var top=0;
            var row=[];
            var classname=('equalHeights'+Math.random()).replace('.','');
            $(this).each(function(){
                var thistop=$(this).offset().top;
                if (thistop>top) {
                    $('.'+classname).removeClass(classname);
                    top=thistop;
                }
                $(this).addClass(classname);
                $(this).height('auto');
                var h=(Math.max.apply(null, $('.'+classname).map(function(){ return $(this).outerHeight(); }).get()));
                $('.'+classname).outerHeight(h);
                //$('.'+classname).css("min-height",(h));
            }).removeClass(classname);
        }
    });

    var equalizeMe = function() {
        var $highest = 1;
        $("[class^='jsEq-']").each(function(idx,ele){
            var $classname = $(this).attr("class");
            var $parts = $classname.split("-");
            if($highest < $parts[1]){
                $highest = $parts[1];
            }
        });

        for(var $i=1; $i<$highest+1; $i++){
            $(".jsEq-"+$i).equalHeights();
        }
    };

    //------------------------------------------------------
    // VIEWPORT RESIZING
    $(window).resize(function () {
        equalizeMe();
    }).trigger("resize");

});
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
h2, p {
  margin-bottom: 0;
}

.column {
  float: left;
  width: 30%;
  margin: 0 1%;
  background: blue;
}

.header {
  background: red;
}

.body {
  background: green
}

.footer {
  background: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>

<div class="column">
	<div class="header jsEq-1">
		<h2>Short heading</h2>
	</div>
	<div class="body jsEq-2">
		<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas metus sapien, vulputate eget molestie eu, ultricies sit amet urna. Donec mollis pharetra tortor, nec sollicitudin ligula sodales vel. Duis feugiat id nunc a maximus. Nulla pretium lorem eu justo tincidunt, eget faucibus ex egestas. Aliquam commodo enim at lorem blandit sodales. Aenean sed tellus vitae nisl imperdiet molestie eget id mauris. Praesent non ullamcorper sapien.</p>
	</div>
	<div class="footer jsEq-3">
		<p>Duis feugiat id nunc a maximus.</p>
	</div>
</div>

<div class="column">
	<div class="header jsEq-1">
		<h2>Medium heading blandit id sollicitudin eget, pellentes</h2>
	</div>
	<div class="body jsEq-2">
		<p>Pellentesque quam augue, blandit id sollicitudin eget, pellentesque in nunc. Curabitur sed purus justo. Maecenas aliquet, purus non porta vestibulum, dolor nisi congue nisi, id tincidunt quam nisi non lacus. Morbi in nunc eget neque rhoncus dapibus. Morbi id orci ligula. Duis elementum, sem eget tempus bibendum, est purus vestibulum felis, ut aliquam sem felis id massa. Aliquam non imperdiet ligula, vitae laoreet nisl. Fusce vehicula metus nec lectus luctus tempor. Integer laoreet ligula quis magna dignissim, sed convallis tellus finibus. Mauris arcu justo, dignissim congue maximus vel, faucibus eu ipsum. Duis ullamcorper mi in risus finibus fermentum. Pellentesque ut metus feugiat arcu ullamcorper elementum et sed nunc. Donec luctus diam a orci elementum, in sollicitudin mauris scelerisque. Morbi aliquet enim enim. Nullam quis pretium lectus. </p>
	</div>
	<div class="footer jsEq-3">
		<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas metus sapien, vulputate eget molestie eu, ultricies sit amet urna. Donec mollis pharetra tortor, nec sollicitudin ligula sodales vel. Duis feugiat id nunc a maximus.</p>
	</div>
</div>

<div class="column">
	<div class="header jsEq-1">
		<h2>Long heading pellentesque quam augue, blandit id sollicitudin eget, pellentesque in nunc</h2>
	</div>
	<div class="body jsEq-2">
		<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas metus sapien, vulputate eget molestie eu, ultricies sit amet urna. Donec mollis pharetra tortor, nec sollicitudin ligula sodales vel. Duis feugiat id nunc a maximus.</p>
	</div>
	<div class="footer jsEq-3">
		<p>Donec mollis pharetra tortor, nec sollicitudin ligula sodales vel. Duis feugiat id nunc a maximus.</p>
	</div>
</div>

Upvotes: 0

Views: 85

Answers (3)

Jecoms
Jecoms

Reputation: 2838

This code seems to work fine. The problem could be in the html, equalHeights function, or the version of jQuery being used.

After OP Edit: The selector

$("[class^='jsEq-']")

was using ^=, which only matches class names that start with the given string. Since you have other class names that are appearing first, you need to use *= to select any tags whose class name contains the given string.

$("[class*='jsEq-']")

I also switched

var $parts = $classname.split("-");
if($highest < $parts[1]){
    $highest = $parts[1];
}

to

var $classNumber = parseInt($classname.substring($classname.indexOf("jsEq-")+5));
if($highest < $classNumber){
    $highest = $classNumber;
}

This is safer in case you have other classes with a dash in them (as is very common with bootstrap for example).

var equalizeMe = function() {
    var $highest = 1;
    $("[class*='jsEq-']").each(function(idx,ele){
        var $classname = $(this).attr("class");

        // this extracts the number after 'jsEq'
        // otherwise, other dash-classes would break your split("-") array method
        var $classNumber = parseInt($classname.substring($classname.indexOf("jsEq-")+5));

        if($highest < $classNumber){
            $highest = $classNumber;
        }
    });

    for(var $i=1; $i<$highest+1; $i++){
        // This is showing the loop works. Check equalHeights()
        $(`.jsEq-${$i}`).html(`.jsEq-${$i} highest = ${$highest}`);
    }
};

equalizeMe();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="test jsEq-1 foo foo-baz"></div>
<div class="text foo-bar jsEq-2"></div>
<div class="stuff jsEq-3"></div>
<div class="foo jsEq-4 dash-this"></div>
<div class="bar jsEq-5 dash-that"></div>

Upvotes: 1

sambadave
sambadave

Reputation: 23

Thanks guys

@MJH - I ended up moving the for loop inside the each() function and changing to [class*='jsEq-'] and it now appears to work. See updated snippet.

$(window).load(function() {

    $.fn.extend({
        equalHeights: function(){
            var top=0;
            var row=[];
            var classname=('equalHeights'+Math.random()).replace('.','');
            $(this).each(function(){
                var thistop=$(this).offset().top;
                if (thistop>top) {
                    $('.'+classname).removeClass(classname);
                    top=thistop;
                }
                $(this).addClass(classname);
                $(this).height('auto');
                var h=(Math.max.apply(null, $('.'+classname).map(function(){ return $(this).outerHeight(); }).get()));
                $('.'+classname).outerHeight(h);
                //$('.'+classname).css("min-height",(h));
            }).removeClass(classname);
        }
    });

    var equalizeMe = function() {
        var $highest = 1;
        $("[class*='jsEq-']").each(function(idx,ele){
            var $classname = $(this).attr("class");
            var $parts = $classname.split("-");
            if($highest < $parts[1]){
                $highest = $parts[1];
            }

            for(var $i=1; $i<$highest+1; $i++){
                $(".jsEq-"+$i).equalHeights();
            }
        });
    };

    //------------------------------------------------------
    // VIEWPORT RESIZING
    $(window).resize(function () {
        equalizeMe();
    }).trigger("resize");

});
* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
h2, p {
  margin-bottom: 0;
}

.column {
  float: left;
  width: 30%;
  margin: 0 1%;
  background: blue;
}

.header {
  background: red;
}

.body {
  background: green
}

.footer {
  background: yellow;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>

<div class="column">
	<div class="header jsEq-1">
		<h2>Short heading</h2>
	</div>
	<div class="body jsEq-2">
		<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas metus sapien, vulputate eget molestie eu, ultricies sit amet urna. Donec mollis pharetra tortor, nec sollicitudin ligula sodales vel. Duis feugiat id nunc a maximus. Nulla pretium lorem eu justo tincidunt, eget faucibus ex egestas. Aliquam commodo enim at lorem blandit sodales. Aenean sed tellus vitae nisl imperdiet molestie eget id mauris. Praesent non ullamcorper sapien.</p>
	</div>
	<div class="footer jsEq-3">
		<p>Duis feugiat id nunc a maximus.</p>
	</div>
</div>

<div class="column">
	<div class="header jsEq-1">
		<h2>Medium heading blandit id sollicitudin eget, pellentes</h2>
	</div>
	<div class="body jsEq-2">
		<p>Pellentesque quam augue, blandit id sollicitudin eget, pellentesque in nunc. Curabitur sed purus justo. Maecenas aliquet, purus non porta vestibulum, dolor nisi congue nisi, id tincidunt quam nisi non lacus. Morbi in nunc eget neque rhoncus dapibus. Morbi id orci ligula. Duis elementum, sem eget tempus bibendum, est purus vestibulum felis, ut aliquam sem felis id massa. Aliquam non imperdiet ligula, vitae laoreet nisl. Fusce vehicula metus nec lectus luctus tempor. Integer laoreet ligula quis magna dignissim, sed convallis tellus finibus. Mauris arcu justo, dignissim congue maximus vel, faucibus eu ipsum. Duis ullamcorper mi in risus finibus fermentum. Pellentesque ut metus feugiat arcu ullamcorper elementum et sed nunc. Donec luctus diam a orci elementum, in sollicitudin mauris scelerisque. Morbi aliquet enim enim. Nullam quis pretium lectus. </p>
	</div>
	<div class="footer jsEq-3">
		<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas metus sapien, vulputate eget molestie eu, ultricies sit amet urna. Donec mollis pharetra tortor, nec sollicitudin ligula sodales vel. Duis feugiat id nunc a maximus.</p>
	</div>
</div>

<div class="column">
	<div class="header jsEq-1">
		<h2>Long heading pellentesque quam augue, blandit id sollicitudin eget, pellentesque in nunc</h2>
	</div>
	<div class="body jsEq-2">
		<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas metus sapien, vulputate eget molestie eu, ultricies sit amet urna. Donec mollis pharetra tortor, nec sollicitudin ligula sodales vel. Duis feugiat id nunc a maximus.</p>
	</div>
	<div class="footer jsEq-3">
		<p>Donec mollis pharetra tortor, nec sollicitudin ligula sodales vel. Duis feugiat id nunc a maximus.</p>
	</div>
</div>

Upvotes: 0

MJH
MJH

Reputation: 2307

The [class^='jsEq-'] selector in the equalizeMe function is targeting elements having classes that begin with the string jsEq-, but no such elements exist. All your "class" values actually begin with either "header", "body", or "footer".

Therefore, $highest is never modified from its initial value of 1, so the subsequent for loop runs only once, which is why only the red boxes have equal heights.

To resolve this issue, target elements whose "class" values contain the string "jsEq-" instead.

Just change this line:

$("[class^='jsEq-']").each(function(idx,ele){

To this:

$("[class*='jsEq-']").each(function(idx,ele){


Upvotes: 1

Related Questions