dungey_140
dungey_140

Reputation: 2802

jQuery .each() for repeating elements

I'm trying to use jQuery to detect the orientation of a number of images. Once detected, I want to add a class to indicate this i.e .landscape.

The code below seems to only be assessing the first image it comes across, and then applying that to all subsequent images. For example, if the first image is landscape, this will be applied to all images including portrait or square image.

Am I misusing the .each() statement?

Thank you.

HTML

<div class="carousel-cell">
    <img src="domain.com" data-width="100" data-height="200" />
</div>
<div class="carousel-cell">
    <img src="domain.com" data-width="200" data-height="100" />
</div>
<div class="carousel-cell">
    <img src="domain.com" data-width="100" data-height="100" />
</div>

JQUERY

// Detect image orientation 
$('.carousel-cell').each(function () {
"use strict";

var img = $('img');

if (img.attr('data-width') > img.attr('data-height')){
    // Landscape
    img.removeClass().addClass('landscape');
} else if (img.attr('data-width') < img.attr('data-height')){
    // Portrait
    img.removeClass().addClass('portrait');
} else {
    // Equal (Square)
    img.removeClass().addClass('square');
}
});

Upvotes: 1

Views: 686

Answers (2)

Tyler Roper
Tyler Roper

Reputation: 21672

In each loop, you're selecting $("img"), which is every <img> on the page.

You need to limit your search to find the img within the current element, using $(this).find("img") instead.

// Detect image orientation 
$('.carousel-cell').each(function() {
  "use strict";

  var $img = $(this).find('img');
  var w = parseInt($img.attr("data-width"));
  var h = parseInt($img.attr("data-height"));
  $img.removeClass();

  if (w > h) {
    $img.addClass('landscape');
  } else if (w < h) {
    $img.addClass('portrait');
  } else {
    $img.addClass('square');
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<span><strong>Right click on image > Inspect Element</strong> to see classes.</span>

<div class="carousel-cell">
  <img src="domain.com" data-width="100" data-height="200" />
</div>
<div class="carousel-cell">
  <img src="domain.com" data-width="200" data-height="100" />
</div>
<div class="carousel-cell">
  <img src="domain.com" data-width="100" data-height="100" />
</div>

EDIT: Per your comment about the weird behavior, I suspect it's simply because you're not parsing the width and height as integers, and as such, the > and < comparisons will be done alphabetically. For example, "1000" would be less than "800", because "1" < "8". I've added parseInt() to resolve this.

Upvotes: 1

Hary
Hary

Reputation: 5818

You should use $(this) and then .find image tag inside that.

$(function(){

// Detect image orientation 
    $('.carousel-cell').each(function () {
    "use strict";
    
    var img = $(this).find("img");
    var imgWidth = $(img).attr('data-width');
    var imgHeight = $(img).attr('data-height');
    
    var className = imgWidth > imgHeight 
                    ? "landscape" 
                    : imgWidth < imgHeight
                      ? "portrait"
                      : "square"; 

     $(img).removeClass().addClass(className);
     
    });

});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="carousel-cell">
    <img src="domain.com" data-width="100" data-height="200" />
</div>
<div class="carousel-cell">
    <img src="domain.com" data-width="200" data-height="100" />
</div>
<div class="carousel-cell">
    <img src="domain.com" data-width="100" data-height="100" />
</div>

Upvotes: 0

Related Questions