Search code examples
jquerycssfunctionjquery-1.3

jquery firing issue


I am using a function to equalise the height of li tags returned from a database. I am also using jquery to assign certain li new classes dependant on their position in a row.

Basocally my problem is that the positioning part of the jquery statement always works but the equal heights part will sometimes not fire, in fact it generally doesn't work on an empty cache - it will however always fire on refresh or second visit to the page.

Live example here Link here!(let me know if it works for you!)

The jquery code I am using is listed below.

    jQuery.fn.equalCols = function(){
    //Array Sorter
    var sortNumber = function(a,b){return b - a;};
    var heights = [];
    //Push each height into an array
    $(this).each(function(){
        heights.push($(this).height());
    });
    heights.sort(sortNumber);
    var maxHeight = heights[0];
    return this.each(function(){
        //Set each column to the max height
        $(this).css({'height': maxHeight});
    });
};

jQuery(document).ready(function($) {
        $(".thumbs").each(function(i) { 
        if (i % 4 == 0) 
           $(this).addClass("start");
        if (i % 4 == 3) 
           $(this).addClass("end");
    });
    $(".thumbs").each(function(i) { 
        if (i % 3 == 0) 
           $(this).addClass("start");
        if (i % 3 == 2) 
           $(this).addClass("end");
           });
    $(".event_thumbs").each(function(i) { 
        if (i % 2 == 0) 
           $(this).addClass("start");
           });
$('.thumbs, .end, .start').equalCols();
});

If you have an better suggestions for the code or methods to achieve the aim please shout out or if you know how to make it work - I love you.


Solution

  • Perhaps an issue with not wrapping this in jQuery on the last loop? Also, you only need to keep track of the maximum seen so far as you iterate. Putting the heights into an array and sorting it seems inefficient.

    jQuery.fn.equalCols = function(){
        var maxHeight = 0;
        $(this).each(function(){
            var height = $(this).height();
            if (height && height > maxHeight) maxHeight = height;
        });
    
        return $(this).each(function(){
            //Set each column to the max height
            $(this).css({'height': maxHeight});
        });
    };
    

    Update: Since you have images on the page, it's not enough to wait until the document is loaded, you also need to wait until the images are loaded as well. Or, better yet, simply equalize after every image is loaded -- that way you're certain to do so after all of them are. Since the load handler won't be called if the image is loaded before it is applied (e.g., it may be in the user's cache and load more quickly than the javascript executes), set up a timer to fire the equalCols function after a specified amount of time to cover the case where the load handler isn't invoked for any image. Leave the load handler on the image, then if you change the source to the image it will be reapplied and the page equalized again.

     $(function() {
         $('img').load( function() { /* equalize after every image load */
              equalize();
         });
         setTimeout( equalize, 2000 );  /* wait 2 secs, then equalize */
     });
    
     function equalize() {
         $('.thumbs, .end, .start').equalCols();
     }