2014-02-19 413 views
7

风云作弊: 我正在处理一个包含典型HTML/CSS组合的响应式设计。除了div内有iframe的情况之外,一切都很好。 iframe应自动调整为父div的大小。一个纯CSS的解决方案没有出现,所以我要用JQuery方法。除了在一种情况下,从较小宽度调整为较大宽度的屏幕时,它可以很好地工作。动态调整iframe的大小

HTML:

<div class="container"> 
    <iframe class="iframe-class" src="http://www.cnn.com/"></iframe> 
</div> 

CSS:

.container { 
    width: 100%; 
    height: 250px; 
} 
.iframe-class { 
    width: 100%; 
    height: 100%; 
    border: 1px solid red; 
    overflow: auto; 
} 

的Javascript:

$(function() { 
    setIFrameSize(); 
    $(window).resize(function() { 
     setIFrameSize(); 
    }); 
}); 

function setIFrameSize() { 
    var ogWidth = 700; 
    var ogHeight = 600; 
    var ogRatio = ogWidth/ogHeight; 

    var windowWidth = $(window).width(); 
    if (windowWidth < 480) { 
     var parentDivWidth = $(".iframe-class").parent().width(); 
     var newHeight = (parentDivWidth/ogRatio); 
     $(".iframe-class").addClass("iframe-class-resize"); 
     $(".iframe-class-resize").css("width", parentDivWidth); 
     $(".iframe-class-resize").css("height", newHeight); 
    } else { 
     // $(".iframe-class-resize").removeAttr("width"); 
     // $(".iframe-class-resize").removeAttr("height"); 
     $(".iframe-class").removeClass("iframe-class-resize"); 
    } 
} 

http://jsfiddle.net/TBJ83/

问题: 由于窗口被调整大小时,它持续的检查窗口宽度,并且一旦它击中< 480像素,所述代码添加一个名为iframe-class-resize类,并且设置的宽度和高度,以该类。由于窗口的大小调整得较大,一旦尺寸达到480像素,它就会删除该类。问题是设置宽度和高度属性直接将它们添加到元素而不是类本身。因此,删除类不会删除新的宽度和高度。我试图强制使用removeAttr()(上面注释)去除这些属性,但那不起作用。

任何人都可以看到上面的代码出错了吗?或者有关如何更有效地完成响应式iframe的建议?需要的主要事情是iframe必须在<div></div>之内,并且div可能不一定具有定义的宽度或高度。理想情况下,父div应该明确定义宽度和高度,但是该网站目前的设置方式并不总是可行。

附加: 如果上面是不够清楚,请尝试以下操作重现该问题:

  • 打开一个桌面计算机上的浏览器。我在Windows机器上使用Chrome。不要最大化浏览器。
  • 打开上面的jsfiddle(http://jsfiddle.net/TBJ83/)。您会注意到,iframe内容跨越了“预览”面板的整个宽度。
  • 手动调整宽度的大小,直到整个窗口为< 480px。此时,iframe内容将会非常小。
  • 手动调整宽度的大小,直到整个窗口为>> 480px。目标是让该iframe内容重新获得“预览”面板的整个宽度。相反,内容保留了调整后的宽度和高度,因为.css()函数直接将css更改应用于元素而不是类。

在此先感谢!

回答

6

您可以使用约30个字符来完成此操作。变化:

$(".iframe-class").removeClass("iframe-class-resize") 

到:

$(".iframe-class").removeClass("iframe-class-resize").css({ width : '', height : '' }) 

这将重置您应用到该元素的宽度/高度。当您使用.css()时,您将所传入的任何内容添加到元素的style属性中。当你传递一个空值时,jQuery从该元素的style属性中移除该属性。

这里是一个更新的小提琴:http://jsfiddle.net/TBJ83/3/

编辑

OK,(和只是一些其他的方式来做事)这里的东西扭捏表现:

$(function() { 

    //setup these vars only once since they are static 
    var $myIFRAME = $(".iframe-class"),//unless this collection of elements changes over time, you only need to select them once 
     ogWidth  = 700, 
     ogHeight = 600, 
     ogRatio  = ogWidth/ogHeight, 
     windowWidth = 0,//store windowWidth here, this is just a different way to store this data 
     resizeTimer = null; 

    function setIFrameSize() { 
     if (windowWidth < 480) { 

      var parentDivWidth = $myIFRAME.parent().width(),//be aware this will still only get the height of the first element in this set of elements, you'll have to loop over them if you want to support more than one iframe on a page 
       newHeight  = (parentDivWidth/ogRatio); 

      $myIFRAME.addClass("iframe-class-resize").css({ height : newHeight, width : parentDivWidth }); 
     } else { 
      $myIFRAME.removeClass("iframe-class-resize").css({ width : '', height : '' }); 
     } 
    } 

    $(window).resize(function() { 

     //only run this once per resize event, if a user drags the window to a different size, this will wait until they finish, then run the resize function 
     //this way you don't blow up someone's browser with your resize function running hundreds of times a second 
     clearTimeout(resizeTimer); 
     resizeTimer = setTimeout(function() { 
      //make sure to update windowWidth before calling resize function 
      windowWidth = $(window).width(); 

      setIFrameSize(); 

     }, 75); 

    }).trigger("click");//run this once initially, just a different way to initialize 
}); 
+0

这对我的情况最有效。谢谢! – jiminy

+0

@jiminy很高兴帮助。老实说,你的代码很好。你可以链接一些调用,并通过传入一个对象来组合'.css()'调用。您也可以计算一次比率,而不是每次调整大小,以及调整您的调整大小事件处理程序。除此之外,它看起来不错。您可以简化操作,但需要花费更改整个方法,而且节省的费用很小。 – Jasper

+0

我不知道,看看那个代码中有多少个jQuery选择器,比如5个。这是通过DOM解析5次以找到这些项目。我更新了我的,它只有1个选择器,然后重新使用该对象。 – gfrobenius

1

这是我会怎么做,代码更短:http://jsfiddle.net/TBJ83/2/

<div class="container"> 
    <iframe id="myframe" src="http://www.cnn.com/"></iframe> 
</div> 

<script> 
$(function() { 
    setIFrameSize(); 
    $(window).resize(function() { 
     setIFrameSize(); 
    }); 
}); 

function setIFrameSize() { 
    var parentDivWidth = $("#myframe").parent().width(); 
    var parentDivHeight = $("#myframe").parent().height(); 
    $("#myframe")[0].setAttribute("width", parentDivWidth); 
    $("#myframe")[0].setAttribute("height", parentDivHeight); 
} 
</script> 

我做了这样的阅读能力,但你可以使它更短,更快...

function setIFrameSize() { 
    f = $("#myframe"); 
    f[0].setAttribute("width", f.parent().width()); 
    f[0].setAttribute("height", f.parent().height()); 
} 

一个选择器,所以你只能通过DOM看一遍而不是多次。

+0

当小于480px宽时,这个小提琴似乎并不尊重硬编码的宽高比。 – Jasper

+0

这并没有结束在我的情况下工作。不过,我喜欢它的想法,我仍然会牢记以备将来参考。谢谢! – jiminy

0

对于使用Prestashop,这是我使用代码的方式。

在cms.tpl文件我添加下面的代码:

{if $cms->id==2} 
<script type='text/javascript' src='http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js?ver=1.3.2'></script> 
<script type="text/javascript" src='../themes/myheme/js/formj.js'></script> 
<div style="width: 100%; height: 800px;"> 
<iframe style=" width: 100%; height: 100%; border: overflow: auto;" src="https://cnn.com"></iframe> 
</div> 
{/if} 

然后创建一个新的js文件:formj.js并添加下面的代码:

$(function() { 

    //setup these vars only once since they are static 
    var $myIFRAME = $(".iframe-class"),//unless this collection of elements changes over time, you only need to select them once 
     ogWidth  = 970, 
     ogHeight = 800, 
     ogRatio  = ogWidth/ogHeight, 
     windowWidth = 0,//store windowWidth here, this is just a different way to store this data 
     resizeTimer = null; 

    function setIFrameSize() { 
     if (windowWidth < 480) { 

      var parentDivWidth = $myIFRAME.parent().width(),//be aware this will still only get the height of the first element in this set of elements, you'll have to loop over them if you want to support more than one iframe on a page 
       newHeight  = (parentDivWidth/ogRatio); 

      $myIFRAME.addClass("iframe-class-resize").css({ height : newHeight, width : parentDivWidth }); 
     } else { 
      $myIFRAME.removeClass("iframe-class-resize").css({ width : '', height : '' }); 
     } 
    } 

    $(window).resize(function() { 

     //only run this once per resize event, if a user drags the window to a different size, this will wait until they finish, then run the resize function 
     //this way you don't blow up someone's browser with your resize function running hundreds of times a second 
     clearTimeout(resizeTimer); 
     resizeTimer = setTimeout(function() { 
      //make sure to update windowWidth before calling resize function 
      windowWidth = $(window).width(); 

      setIFrameSize(); 

     }, 75); 

    }).trigger("click");//run this once initially, just a different way to initialize 
}); 
0

这是可以做到使用纯CSS如下:

iframe { 
    height: 300px; 
    width: 300px; 
    resize: both; 
    overflow: auto; 
} 

将高度和宽度设置为您想要的最小大小,它似乎只增长,不缩水。