Situation: Je travaille sur une conception réactive qui comprend le combo HTML/CSS typique. Tout fonctionne bien sauf dans un cas où il y a un iframe à l'intérieur d'un div. L'iframe devrait s'ajuster automatiquement à la taille de la div parente. Une solution purement css ne s'est pas présentée, alors je vais utiliser une approche JQuery. Cela fonctionne bien, sauf dans un scénario, lors du redimensionnement d'une largeur plus petite à un écran plus large.
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");
}
}
Problème: Lorsque la fenêtre est redimensionnée plus petite, elle vérifie en permanence la largeur de la fenêtre et dès qu'elle atteint <480 px, le code ajoute une classe appelée iframe-class-resize
et définit la largeur et la hauteur de cette classe. Lorsque la fenêtre est redimensionnée plus grande, la classe est supprimée dès que la taille atteint 480 px. Le problème est que la définition des attributs width et height les ajoute directement à l'élément et non à la classe elle-même. Par conséquent, la suppression de la classe ne supprime pas les nouvelles largeurs et hauteurs. J'ai essayé de forcer la suppression des attributs en utilisant removeAttr()
(commenté ci-dessus) mais cela n'a pas fonctionné.
Quelqu'un voit où le code ci-dessus a mal tourné? Ou des suggestions sur la façon d'obtenir un iframe réactif plus efficacement? L'essentiel est que l'iframe soit à l'intérieur du <div></div>
et que la div ne puisse pas nécessairement avoir une largeur ou une hauteur définie. Idéalement, la largeur et la hauteur de la div parent devraient être définies explicitement, mais la façon dont ce site est actuellement configuré ne sera pas toujours possible.
Supplémentaire: Si ce qui précède n’est pas assez clair, essayez ce qui suit pour reproduire le problème:
.css()
applique les modifications CSS directement aux éléments plutôt qu'aux classes.Merci d'avance!
Vous pouvez le faire dans environ 30 caractères. Changement:
$(".iframe-class").removeClass("iframe-class-resize")
à:
$(".iframe-class").removeClass("iframe-class-resize").css({ width : '', height : '' })
Cela réinitialisera la largeur/hauteur que vous avez appliquée à l'élément. Lorsque vous utilisez .css()
, vous ajoutez ce que vous transmettez à l'attribut style
de l'élément. Lorsque vous transmettez une valeur vide, jQuery supprime cette propriété de l'attribut style
de l'élément.
Voici un violon mis à jour: http://jsfiddle.net/TBJ83/3/
MODIFIER
OK, voici quelque chose de peaufiné pour la performance (et juste quelques autres façons de faire les choses):
$(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
});
Voici comment je le ferais, le code est beaucoup plus court: 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>
Je l’ai fait de cette façon en lecture-capacité, mais vous pourriez le rendre encore plus court et plus rapide ...
function setIFrameSize() {
f = $("#myframe");
f[0].setAttribute("width", f.parent().width());
f[0].setAttribute("height", f.parent().height());
}
Un sélecteur, de sorte que vous ne parcourez le DOM qu'une seule fois au lieu de plusieurs fois.
Cela peut être fait en utilisant du CSS pur comme ci-dessous:
iframe {
height: 300px;
width: 300px;
resize: both;
overflow: auto;
}
Réglez la hauteur et la largeur sur la taille minimale souhaitée, elle semble seulement grossir, pas rétrécir.
Pour ceux qui utilisent Prestashop, voici comment j'ai utilisé le code.
Dans le fichier cms.tpl, j'ai ajouté le code ci-dessous:
{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}
Puis créé un nouveau fichier js: formj.js et ajouté le code ci-dessous:
$(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
});