4

I have an iframe of a video inside a div, like so:

<div class="media">
    <iframe>
</div>

I set the DIV's size dynamically on window resize.

I want to scale the iframe to fit inside the div, while maintaining it's aspect ratio. Most of the code out there deals with scaling images, which is easier.

This is what I have so far, but it doesn't work:

jQuery.fn.fitToParent = function()
{
    this.each(function()
    {
        var width  = jQuery(this).width();
        var height = jQuery(this).height();
        var parentWidth  = jQuery(this).parent().width();
        var parentHeight = jQuery(this).parent().height();

        if(width < parentWidth)
        {
            newWidth  = parentWidth;
            newHeight = newWidth/width*height;
        }
        else
        {
            newHeight = parentHeight;
            newWidth  = newHeight/height*width;
        }

        jQuery(this).css({
            'height'     :newHeight,
            'width'      :newWidth'
        });
    });
};

Basically, I'm looking to replicate the sizing that "background-size: contain" does for images in CSS, but for an iframe in a DIV.

Thanks for the help!

4

3 回答 3

7

注意到三个问题:

  1. 您的示例中有一个错误(尾随引号):

    :newWidth'

  2. 您需要设置 iframe 的实际高度和宽度属性,而不是样式。设置 iframe 大小的样式无效:

    $(this).width(newWidth);
    $(this).height(newHeight);
    
  3. 纵横比的计算是错误的(需要比较比率以查看它们重叠的方式)。没有这个,并不是所有的重叠情况都能得到满足。

    var aspect = width/height;
    var parentAspect = parentWidth/parentHeight;
    if (aspect > parentAspect)
    {
        newWidth  = parentWidth;
        newHeight = newWidth / aspect;
    }
    else
    {
        newHeight = parentHeight;
        newWidth  = newHeight * aspect;
    }
    

我还稍微清理了代码以加快元素访问速度。每次调用 jQuery(this) 都会花费周期。

JSFiddle在这里:http: //jsfiddle.net/TrueBlueAussie/ZJDkF/8/

更新:

jsfiddle 现在有 4 种不同重叠场景的示例,每个场景都保留了 iframe 的比例。我还添加了您提到的窗口调整大小,并使用它动态调整第一个 div 的大小以进行演示。

于 2013-09-19T11:53:35.117 回答
3

随着时间的推移,我确实改进了@TrueBlueAussie 的答案,并认为我会在此处发布更复杂的答案以供将来参考。

在这里将其作为 GitHub 上的插件:https ://github.com/drewbaker/fitToParent

这是jQuery插件:

jQuery.fn.fitToParent = function (options) {

    this.each(function () {

        // Cache the resize element
        var $el = jQuery(this);

        // Get size parent (box to fit element in)
        var $box;
        if( $el.closest('.size-parent').length ) {
            $box = $el.closest('.size-parent');
        } else {
            $box = $el.parent();
        }

        // These are the defaults.
        var settings = jQuery.extend({  
                height_offset: 0,
                width_offset: 0,
                box_height: $box.height(),
                box_width: $box.width(),
        }, options );

        // Setup box and element widths
        var width = $el.width();
        var height = $el.height();
        var parentWidth = settings.box_width - settings.width_offset;
        var parentHeight = settings.box_height - settings.height_offset;

        // Maintin aspect ratio
        var aspect = width / height;
        var parentAspect = parentWidth / parentHeight;

        // Resize to fit box
        if (aspect > parentAspect) {
            newWidth = parentWidth;
            newHeight = (newWidth / aspect);
        } else {
            newHeight = parentHeight;
            newWidth = newHeight * aspect;
        }

        // Set new size of element
        $el.width(newWidth);
        $el.height(newHeight); 

    });
};

所以,假设你有这样的 HTML:

<div id="wrapper">
    <iframe width="720" height="405" src="//player.vimeo.com/video/19223989"></iframe>
</div>

调用插件最基本的方式是这样的:

jQuery('#wrapper iframe').fitToParent();

但我经常将#wrapper 设置为接近窗口的高度和宽度,如下所示:

// Get window height and width
var winHeight = jQuery(window).height();
var winWidth = jQuery(window).width();

// Set wrapper height/width to that of window
jQuery('#wrapper').height(winHeight).width(winWidth);

// Size Iframe
jQuery('#wrapper iframe').fitToParent({
    height_offset: 100, // Put some space around the video
    width_offset: 100, // Put some space around the video
});

您还可以输入自定义框大小以适应元素,如下所示:

// Get window height and width
var winHeight = jQuery(window).height();
var winWidth = jQuery(window).width();

// Size element
jQuery('#wrapper iframe').fitToParent({
    height_offset: 100, // Put some space around the video
    width_offset: 100, // Put some space around the video
    box_height: winHeight, // Force use of this box size
    box_width: winWidth // Force use of this box size
});

我还添加了将 CSS 类“size-parent”设置为父元素的功能,然后它将使用该父元素作为框大小。一个完整的例子:

// HTML like this
<div id="wrapper" class="size-parent">
    <div class="media">
        <iframe width="720" height="405" src="//player.vimeo.com/video/19223989"></iframe>
    </div>
</div>

// jQuery like this
jQuery('.media iframe').fitToParent();    

如果您不设置 .size-parent,它将回退到元素父级。如果您设置 box_height/box_width 参数,那么这些参数显然会覆盖所有内容。

现在,为了展示它的强大功能,试试这个垂直居中、水平居中宽高比正确的 iFrame!

// CSS like this
#wrapper {
    text-align: center;
    display: table-cell;
    vertical-align: middle;
}
#wrapper iframe {
    display: inline-block;
}

// HTML like this
<div id="wrapper" class="size-wrapper">
    <iframe width="720" height="405" src="//player.vimeo.com/video/19223989"></iframe>
</div>

// jQuery like this
// Get window height and width
var winHeight = jQuery(window).height();
var winWidth = jQuery(window).width();

// Size wrapper
jQuery('#wrapper').height( winHeight ).width( winWidth );

// Size element
jQuery('#wrapper iframe').fitToParent({
    height_offset: 200, // Put some space around the video
    width_offset: 200, // Put some space around the video
});

// Fit iFrame to wrapper
jQuery('#wrapper iframe').fitToParent();

在现实生活中,我将 jQuery 包装在一个函数中,然后在调整窗口大小时调用该函数以获得真正的响应式 iFrame!

于 2014-08-09T19:45:58.873 回答
0

这里:

http://jsfiddle.net/fFTS8/

  <div id="test" style="width:300px;height:200px;background:red;"></div>
  <script src="js/vendor/jquery-1.10.2.min.js"></script>
  <script type="text/javascript">
     jQuery.fn.fitToParent = function()
     {
        var that = this;

        function rezise() {
           that.each(function()
           {
             var a = $(this).width();
             var b = $(this).height();
             var c = $(this).parent().width();
             var d = $(this).parent().height();

             var ab = a/b;
             var cd = c/b;

             var e, f = 0; // e - newWidth, f - newHeight

             if(ab > cd) {
                e = c;
                f = c*b/a;
             } else {
                e = a*d/b;
                f = d;
             }

             $(this).width(e);
             $(this).height(f);
           });
        }

        $(window).resize(function() {
           rezise();
        });
     };
     $('#test').fitToParent();

  </script>
于 2013-09-19T11:24:21.547 回答