迭代图像(jQuery)进行动态调整大小/定位(CSS)

时间:2015-03-17 20:54:06

标签: jquery html css twitter-bootstrap

我正在构建一个jQuery脚本来在页面加载或调整大小时调整图像元素的大小和位置。我正在使用Bootstrap进行布局。我用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"
            });
        }
    }

});

我知道那里有插件,但我想尝试这个没有任何插件。我只是坚持循环。

1 个答案:

答案 0 :(得分: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通过.each()函数 NOT jQuery对象传递常规DOM对象。因此,为了作为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"
         });
     }
 });

});