Search code examples
jquerycssimageonloaddimensions

Measuring width & height of images returns 0 in Chrome and Firefox, but works in Safari


I'm trying to give my images a landscape or portrait class in a Wordpress image gallery by measuring the images' dimensions on load. The code works in Safari, but Firefox returns a 0 pixel width and height, and Chrome sometimes loads them properly, and sometimes not. I'm pretty confused, could someone help me out?

jQuery(window).on('load', function () {

    jQuery(".blocks-gallery-grid img").each(function() {

        var aspectRatio = jQuery(this).css('width', 'auto').width()/jQuery(this).css('height', 'auto').height();
            console.log(jQuery(this).attr('src'));
            console.log(jQuery(this).width());
            console.log(jQuery(this).height());
        jQuery(this).data("aspect-ratio", aspectRatio);

        if(aspectRatio > 1) {
            jQuery(this).parent().parent().parent('li').addClass( "landscape" );

        } else if (aspectRatio < 1) {
            jQuery(this).parent().parent().parent('li').addClass( "portrait" );
        } else {
            jQuery(this).parent().parent().parent('li').addClass( "landscape" );           
        }
    });
});

Solution

  • $(window).on('load', function() { 
        $(".blocks-gallery-grid img").each(function() {
            let _this = $(this),
                aspectRatio = _this.width()/_this.height(),
                parentLi = _this.closest('li');
                
            if(aspectRatio > 1) {
                parentLi.addClass( "landscape" );
            } else if (aspectRatio < 1) {
                parentLi.addClass( "portrait" );
            } else {
                parentLi.addClass( "landscape" );           
            }
        });
    });
    img{
      max-width: 100%;
    }
    li{
       padding: 15px; 
       box-sizing: border-box; 
       border: 3px solid;
    }
    .landscape{
       border-color: red;
    }
    .portrait{
       border-color: green;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <ul class="blocks-gallery-grid">
      <li>
        <img src="https://dummyimage.com/600x400/000/fff">
      </li>
      <li>
        <img src="https://dummyimage.com/400x600/000/fff">
       </li>
    </ul>

    Could you try something like this:

    $(window).on('load', function () {
    
        $(".blocks-gallery-grid img").each(function() {
            let _this = $(this);
    
            let aspectRatio = _this.width()/_this.height();
    
            _this.data("aspect-ratio", aspectRatio);
    
            if(aspectRatio > 1) {
                _this.parent().parent().parent('li').addClass( "landscape" );
    
            } else if (aspectRatio < 1) {
                _this.parent().parent().parent('li').addClass( "portrait" );
            } else {
                _this.parent().parent().parent('li').addClass( "landscape" );           
            }
        });
    });
    

    Also, I assume li is the only list item parent for that element, so you could probably omit all the .parent() selectors and use: .closest().