2015-03-17 2 views
0

Я создаю скрипт jQuery для определения размеров и размещения элементов изображения при загрузке или изменении размера страницы. Я использую Bootstrap для моего макета. Я использую фиксированную высоту с CSS. Помимо разработки, я не буду контролировать размер или пропорции изображений.Итерации через изображения (jQuery) для динамического определения размера/позиционирования (CSS)

Я построил небольшой скрипт локально, который получает математику и if заявления для изображений разных размеров и пропорций. Теперь мне нужно его обернуть (я думаю) в цикле jQuery each().

Я пробовал один цикл, обернутый вокруг основного скрипта, который нацеливает каждый элемент на класс .listing-box. Затем я попытался добавить еще один (вложенный) цикл, чтобы нацелить фактическое изображение внутри. В итоге я получаю первые вычисления, применяемые ко всем последующим изображениям. Я не знаю, как правильно реализовать each().

JSBin (single image)

JSBin (multiple images)

HTML

<div class="row"> 
    <div class="col-sm-3"> 
     <a href="#"> 
      <div class="listing-box"> 
       <div class="listing"> 
        <img src="http://placehold.it/600x400" alt="thumbnail" class="thumb"> 
       </div> 
      </div> 
     </a> 
    </div> 
</div> 

CSS

.listing-box { 
    width: 100%; 
    height: 220px; 
    position: relative; 
    overflow: hidden; 
} 
.thumb { 
    overflow: hidden; 
} 

JQuery

$(window).on('resize load', function() { 
    // get .listing-box width and height 
    var boxWidth = $(".listing-box").width(); 
    var boxHeight = $(".listing-box").height(); 
    var boxAspect = (boxWidth/boxHeight); 

    // get .thumb width and height 
    var imgWidth = $(".thumb").width(); 
    var imgHeight = $(".thumb").height(); 
    var imgAspect = (imgWidth/imgHeight); 

    // set some empty variables 
    var newWidth, 
     newHeight, 
     mTop, 
     mLeft; 

    if (imgAspect < 1) { 
     // image is VERTICAL 
     // assign values 
     newWidth = boxWidth; 
     newHeight = newWidth * imgHeight/imgWidth; 
     mTop = (newHeight - boxHeight)/2; 

     // use new values for inline css 
     $(".thumb").css({ 
      width: newWidth + "px", 
      height: newHeight + "px", 
      marginTop: "-" + mTop + "px" 
     }); 
    } else { 
     // image is HORIZONTAL 
     if (imgAspect > boxAspect) { 
      // image is more wider than taller 
      // assign values 
      newHeight = boxHeight; 
      newWidth = newHeight * imgWidth/imgHeight; 
      mLeft = (newWidth - boxWidth)/2; 

      // use new values for inline css 
      $(".thumb").css({ 
       width: newWidth + "px", 
       height: newHeight + "px", 
       marginLeft: "-" + mLeft + "px" 
      }); 
     } else { 
      // image is more taller than wider 
      // assign values 
      newWidth = boxWidth; 
      newHeight = newWidth * imgHeight/imgWidth; 
      mTop = (newHeight - boxHeight)/2; 

      // use new values for inline css 
      $(".thumb").css({ 
       width: newWidth + "px", 
       height: newHeight + "px", 
       marginTop: "-" + mTop + "px" 
      }); 
     } 
    } 

}); 

Я знаю, что для этого есть плагины, но я бы хотел попробовать это без каких-либо проблем. Я просто зациклился.

+0

Пожалуйста, покажите свою попытку 'each()'. – isherwood

+0

@isherwood Я должен был упомянуть ... Я оставил комментарии в разделе JavaScript JSBin (несколько изображений), где я поместил свои попытки 'each()'. – Jeannie

ответ

1

Вы близко. Вам нужно обернуть всю функцию в .each() петли следующим образом:

$(window).on('resize load', function() { 
$('.listing-box').each(function() { 

    var boxWidth = $(".listing-box").width(); 
    var boxHeight = $(".listing-box").height(); 
    var boxAspect = (boxWidth/boxHeight); 

    // get .thumb width and height 
    var imgWidth = $(".thumb").width(); 
    var imgHeight = $(".thumb").height(); 
    var imgAspect = (imgWidth/imgHeight); 

    // etc... 
}); 
}); 

Однако, если вы просто сделать это, JQuery собирается, каждый раз он находит .listing-box элемент, возьмите ВСЕ.listing-box и .thumb и примените к нему свою логику калибровки. Что вам нужно, чтобы нацелиться на конкретный элемент .listing-box, который в настоящее время находится внутри каждого цикла, и это .thumb ребенок. То, как вы делаете это с this:

$(window).on('resize load', function() { 
$('.listing-box').each(function() { 

    //Get the width & height for the current .listing-box element 
    //within the loop 
    var boxWidth = $(this).width(); 
    var boxHeight = $(this).height(); 
    var boxAspect = (boxWidth/boxHeight); 

    // Get the width and height for the child of the current 
    //.listing-box element that has the .thumb class 
    var imgWidth = $(this).find('.thumb').width(); 
    var imgHeight = $(this).find('.thumb').height(); 
    var imgAspect = (imgWidth/imgHeight); 

    // etc... 
}); 
}); 

Примечание: Jquery проходит регулярные DOM объектов с помощью функции .each(), NOT объектов JQuery. Таким образом, чтобы получить доступ к текущему элементу внутри каждого цикла в качестве объекта jQuery, его нужно обернуть в селектор jQuery: $(this).

Может быть сложно отслеживать this с вложенными циклами, поэтому лучше всего хранить this в переменной в начале функции. Таким образом, с этими изменениями ваша функция должна выглядеть так:

$(window).on('resize load', function() { 
$('.listing-box').each(function() { 

    //Get the current .listing-box element (and it's .thumb) 
    //that has been passed to the loop and store it in a variable 
    var $box = $(this); 
    var $thumb = $(this).find('.thumb'); 

    // get .listing-box width and height 
    var boxWidth = $box.width(); 
    var boxHeight = $box.height(); 
    var boxAspect = (boxWidth/boxHeight); 

    // get .thumb width and height 
    var imgWidth = $thumb.width(); 
    var imgHeight = $thumb.height(); 
    var imgAspect = (imgWidth/imgHeight); 

    // set some empty variables 
    var newWidth, 
     newHeight, 
     mTop, 
     mLeft; 

    if (imgAspect < 1) { 
    // image is VERTICAL 
    // assign values 
    newWidth = boxWidth; 
    newHeight = newWidth * imgHeight/imgWidth; 
    mTop = (newHeight - boxHeight)/2; 

    // use new values for inline css 
    $thumb.css({ 
     width: newWidth + "px", 
     height: newHeight + "px", 
     marginTop: "-" + mTop + "px" 
    }); 
    } else { 
    // image is HORIZONTAL 
    if (imgAspect > boxAspect) { 
     // image is more wider than taller 
     // assign values 
     newHeight = boxHeight; 
     newWidth = newHeight * imgWidth/imgHeight; 
     mLeft = (newWidth - boxWidth)/2; 

     // use new values for inline css 
     $thumb.css({ 
      width: newWidth + "px", 
      height: newHeight + "px", 
      marginLeft: "-" + mLeft + "px" 
     }); 
    } else { 
     // image is more taller than wider 
     // assign values 
     newWidth = boxWidth; 
     newHeight = newWidth * imgHeight/imgWidth; 
     mTop = (newHeight - boxHeight)/2; 

     // use new values for inline css 
     $thumb.css({ 
      width: newWidth + "px", 
      height: newHeight + "px", 
      marginTop: "-" + mTop + "px" 
     }); 
    } 
}); 

}); 
+0

Большое спасибо за объяснение. Теперь я понимаю 'each()' ** и ** 'this' намного лучше. – Jeannie