Remplacer le style de corps pour le contenu dans une iframe

165

Comment puis-je contrôler l'image d'arrière-plan et la couleur d'un élément de corps dans un iframe? Notez que l'élément body incorporé a une classe et le iframeest d'une page qui fait partie de mon site.

La raison pour laquelle j'en ai besoin est que mon site a un arrière-plan noir attribué au corps, puis un arrière-plan blanc attribué aux divs contenant du texte. Un éditeur WYSIWYG utilise un iframepour incorporer le contenu lors de l'édition, mais il n'inclut pas le div, donc le texte est très difficile à lire.

Le corps du iframewhen dans l'éditeur a une classe qui n'est utilisée nulle part ailleurs, donc je suppose que cela a été mis là pour que des problèmes comme celui-ci puissent être résolus. Cependant, lorsque j'applique des styles, class.bodyils ne remplacent pas les styles appliqués au corps. Ce qui est étrange, c'est que les styles apparaissent dans Firebug, donc je n'ai aucune idée de ce qui se passe!

Merci

MISE À JOUR - J'ai essayé la solution de @ mikeq d'ajouter un style à la classe qui est la classe du corps. Cela ne fonctionne pas lorsqu'il est ajouté à la feuille de style de la page principale, mais cela fonctionne lorsqu'il est ajouté avec Firebug. Je suppose que c'est parce que Firebug est appliqué à tous les éléments de la page alors que le CSS n'est pas appliqué dans les iframes. Cela signifie-t-il que l'ajout du css après le chargement de la fenêtre avec JavaScript fonctionnerait?

jd6699
la source
1
Possible duplicata de Comment appliquer CSS à iframe?
2540625
Bien qu'il ne soit pas possible de toucher quoi que ce soit dans un iframe, charger cette URL par Ajax dans un <div>peut parfois être une solution de contournement (si CORS-Header le permet) ... (et «nettoyer» les données chargées par une expression rationnelle sur le Oui, tous hacky ...)
Frank Nocke
Vous pouvez utiliser javascript si les domaines de la page correspondent, mais pourquoi ne pas simplement mettre un bloc de style dans le code HTML de votre page interne pour remplacer les couleurs que vous souhaitez modifier? Ajoutez simplement plus de sélecteurs dans votre remplacement ou utilisez important! si tout le reste échoue, pour remplacer les styles de couleur que vous voulez uniquement sur cette page ...
OG Sean

Réponses:

112

Un iframe est un «trou» dans votre page qui affiche une autre page Web à l'intérieur. Le contenu de l'iframe n'est sous aucune forme ni ne fait partie de votre page parent.

Comme d'autres l'ont indiqué, vos options sont:

  • donnez au fichier qui est chargé dans l'iframe le CSS nécessaire
  • si le fichier dans l'iframe provient du même domaine que votre parent, vous pouvez accéder au DOM du document dans l'iframe à partir du parent.
DA.
la source
251

Ce qui suit ne fonctionne que si le contenu iframe provient du même domaine parent.

Le script jquery suivant fonctionne pour moi. Testé sur Chrome et IE8. L'iframe interne fait référence à une page qui se trouve sur le même domaine que la page parent.

Dans ce cas particulier, je cache un élément avec une classe spécifique dans l'iframe interne.

Fondamentalement, vous ajoutez simplement un élément 'style' à la 'tête' de l'iframe interne.

$('iframe').load( function() {
    $('iframe').contents().find("head")
      .append($("<style type='text/css'>  .my-class{display:none;}  </style>"));
});
SimpleSam5
la source
4
@ SimpleSam5 Pouvez-vous fournir l'alternative Javascript (sans utiliser Jquery)?
Kamalakannan J
1
@sincerekamal Voici le code sans avoir besoin de jQuery: jsfiddle.net/9g9wkpon Vous avez juste besoin de savoir que les propriétés CSS avec trait d'union sont écrites en camelCase en JavaScript, comme dans mon exemple. :)
Dennis98
2
jquery.js ver = 1.12.4: 2 Uncaught DOMException: Impossible de lire la propriété « contentDocument » de « HTMLIFrameElement »: bloqué un cadre avec l' origine « xxxxxxxxx.com » d'accéder à un cadre transversal d'origine.
Alex Stanese
2
@AlexStanese comme le dit jeremy, cela ne fonctionne que si la page iframe provient du même serveur que la page parent ... ce qui signifie généralement que vous n'avez pas besoin de vous soucier de javascript de toute façon ... ajoutez simplement le CSS à l'autre page en premier lieu.
DA.
@KamalakannanJ vous n'avez même pas besoin d'utiliser Javascript. Modifiez simplement la page qui se trouve dans l'iFrame et placez-y le CSS.
DA.
25

Vous ne pouvez pas changer le style d'une page affichée dans une iframe à moins d'avoir un accès direct et donc la propriété des fichiers source html et / ou css.

C'est pour arrêter XSS (Cross Site Scripting)

Myles Gray
la source
Qu'entendez-vous par «accès direct»? La page dans l'iframe provient de mon site, c'est un seul domaine.
jd6699
2
Eh bien, vous devrez changer le fichier source sur votre site (vous ne pouvez modifier aucun contenu dans une iframe) - donc si l'iframe pointe vers mysite.com/test.html, vous devrez modifier test.html directement. .
Myles Gray le
1
Ne peux pas? Dans les conditions, le PO dit que vous pouvez. Par exemple, son URL iframe interne est la même que celle de son site parent, il devrait donc pouvoir accéder au DOM avec n'importe quel type de javascript que vous aimez ...
OG Sean
@Myles Gray Wrong. Vous pouvez modifier le contenu d'une iframe à partir de sa page parent si elle se trouve sur le même domaine, à la fois avec JavaScript et CSS.
Kevin M
8

An iframea une autre portée, vous ne pouvez donc pas y accéder pour le style ou pour modifier son contenu avec javascript.

C'est essentiellement "une autre page".

La seule chose que vous pouvez faire est d'éditer son propre CSS, car avec votre CSS global, vous ne pouvez rien faire.

Alessandro Vendruscolo
la source
Oui, vous pouvez, avec javascript. Notez que cela fonctionne mieux avec l'URL iframe et l'URL parent partageant le même domaine. Mais, je pense que vous avez raison de souligner que cela peut simplement être fait avec CSS sur la page à l'intérieur de l'iframe.
OG Sean
8

Remplacer un autre domaine iframe CSS

En utilisant une partie de la réponse de SimpleSam5 , j'ai réalisé cela avec quelques iframes de chat de Tawk (leur interface de personnalisation est correcte mais j'avais besoin de personnalisations supplémentaires).

Dans cette iframe particulière qui apparaît sur les appareils mobiles, j'avais besoin de masquer l'icône par défaut et de placer l'une de mes images d'arrière-plan. J'ai fait ce qui suit:

Tawk_API.onLoad = function() {
// without a specific API, you may try a similar load function
// perhaps with a setTimeout to ensure the iframe's content is fully loaded
  $('#mtawkchat-minified-iframe-element').
    contents().find("head").append(
     $("<style type='text/css'>"+
       "#tawkchat-status-text-container {"+
         "background: url(https://example.net/img/my_mobile_bg.png) no-repeat center center blue;"+
         "background-size: 100%;"+
       "} "+
       "#tawkchat-status-icon {display:none} </style>")
   );
};

Je ne possède aucun domaine Tawk et cela a fonctionné pour moi, vous pouvez donc le faire même si ce n'est pas du même domaine parent (malgré le commentaire de Jeremy Becker sur la réponse de Sam).

CPHPython
la source
18
Je soupçonne que cela ne fonctionne que parce que les gens de Tawk l'ont explicitement autorisé.
Lawyerson
@CPHPython Vous pouvez peut-être m'aider. Regardez ceci: stackoverflow.com/questions/60923168/…
Success Man
7

Ce code utilise du JavaScript vanille. Cela crée un nouvel <style>élément. Il définit le contenu textuel de cet élément comme une chaîne contenant le nouveau CSS. Et il ajoute cet élément directement à l'en-tête du document iframe.

var iframe = document.getElementById('the-iframe');
var style = document.createElement('style');
style.textContent =
  'body {' +
  '  background-color: some-color;' +
  '  background-image: some-image;' +
  '}' 
;
iframe.contentDocument.head.appendChild(style);
2540625
la source
7
Blocked a frame with origin xxxxxxxxx from accessing a cross-origin frame.J'ai peur que cela ne fonctionnera pas
Mike
1

Si vous avez le contrôle de la page hébergeant l'iframe et de la page de l'iframe, vous pouvez passer un paramètre de requête à l'iframe ...

Voici un exemple pour ajouter une classe à l'iframe selon que le site d'hébergement est mobile ou non ...

Ajout d'iFrame:

var isMobile=$("mobile").length; //detect if page is mobile
var iFrameUrl ="https://myiframesite/?isMobile=" + isMobile; 

$(body).append("<div id='wrapper'><iframe src=''></iframe></div>");
$("#wrapper iframe").attr("src", iFrameUrl ); 

À l'intérieur d'iFrame:

//add mobile class if needed
var url = new URL(window.location.href);
var isMobile = url.searchParams.get("isMobile");
if(isMobile == "1") {
    $("body").addClass("mobile");
}
Ben
la source
Peut-être que tu peux m'aider. Regardez ceci: stackoverflow.com/questions/60923168/…
Success Man
0

J'ai un blog et j'ai eu beaucoup de mal à trouver comment redimensionner mon contenu intégré. Le gestionnaire de publication vous permet uniquement d'écrire du texte, de placer des images et d'intégrer du code HTML. La mise en page du blog est elle-même réactive. Il est construit avec Wix. Cependant, le HTML intégré ne l'est pas. J'ai beaucoup lu sur l'impossibilité de redimensionner les composants à l'intérieur du corps des iFrames générés. Alors, voici ma suggestion:

Si vous n'avez qu'un seul composant dans votre iFrame, c'est-à-dire votre essence, vous ne pouvez redimensionner que l'essentiel. Oubliez l'iFrame.

J'ai eu des problèmes avec la fenêtre d'affichage, des mises en page spécifiques à différents agents utilisateurs et c'est ce qui a résolu mon problème:

<script language="javascript" type="text/javascript" src="https://gist.github.com/roliveiravictor/447f994a82238247f83919e75e391c6f.js"></script>

<script language="javascript" type="text/javascript">

function windowSize() {
  let gist = document.querySelector('#gist92442763');

  let isMobile = {
    Android: function() {
        return /Android/i.test(navigator.userAgent)
    },
    BlackBerry: function() {
        return /BlackBerry/i.test(navigator.userAgent)
    },
    iOS: function() {
        return /iPhone|iPod/i.test(navigator.userAgent)
    },
    Opera: function() {
        return /Opera Mini/i.test(navigator.userAgent)
    },
    Windows: function() {
        return /IEMobile/i.test(navigator.userAgent) || /WPDesktop/i.test(navigator.userAgent)
    },
    any: function() {
        return (isMobile.Android() || isMobile.BlackBerry() || isMobile.iOS() || isMobile.Opera() || isMobile.Windows());
    }
};

  if(isMobile.any()) {
    gist.style.width = "36%";
    gist.style.WebkitOverflowScrolling = "touch"
    gist.style.position = "absolute"
  } else {
    gist.style.width = "auto !important";
  }
}

windowSize();

window.addEventListener('onresize', function() {
    windowSize();
});

</script>

<style type="text/css">

.gist-data {
  max-height: 300px;
}

.gist-meta {
  display: none;
}

</style>

La logique est de définir gist (ou votre composant) css en fonction de l'agent utilisateur. Assurez-vous d'abord d'identifier votre composant avant de l'appliquer au sélecteur de requête. N'hésitez pas à jeter un coup d'œil sur le fonctionnement de la réactivité .

Victor R. Oliveira
la source
-3

Peut-être que cela a changé maintenant, mais j'ai utilisé une feuille de style séparée avec cet élément:

.feedEkList iframe
{
max-width: 435px!important;
width: 435px!important;
height: 320px!important;
}

pour styliser avec succès les iframes youtube intégrées ... consultez les articles de blog sur cette page .

Tim Jackson
la source
4
Bien que ce lien puisse répondre à la question, il est préférable d'inclure les parties essentielles de la réponse ici et de fournir le lien pour référence. Les réponses aux liens uniquement peuvent devenir invalides si la page liée change.
Shaiful Islam
4
Cela ne s'applique qu'à l'élément iFrame lui-même - la question porte spécifiquement sur le contenu iFrame, qu'il n'est actuellement pas possible de modifier uniquement via CSS.
pwdst
@ShaifulIslam, c'est précisément ce qui s'est passé. Rending Tims répond inutile.
Alex Foxleigh
-24

donnez au corps de votre page iframe un identifiant (ou une classe si vous le souhaitez)

<html>
<head></head>
<body id="myId">
</body>
</html>

puis, également dans la page de l'iframe, attribuez un arrière-plan à celui en CSS

#myId {
    background-color: white;
}
Mikeq
la source
C'est bizarre. Votre solution fonctionne pour moi lorsque je l'ajoute à la page avec firebug, mais ne fonctionne pas si elle se trouve dans le fichier css normal de la page. Cela pourrait-il faire partie de votre commentaire "en supposant que la page dans l'iFrame est à vous de modifier"? Je n'ai pas compris ce que vous vouliez dire par là. Merci
jd6699
Je veux dire par là, la page que vous chargez dans l'iFrame est-elle depuis votre site et sous votre contrôle? ou est-ce à partir d'un site externe que vous ne pouvez pas modifier la source pour inclure cet identifiant / cette classe.
mikeq
Il provient de mon site, mais comme il est fait par l'éditeur, il ne sera pas facile de changer le balisage qui est extrait.
jd6699
ps Je ne voulais pas ajouter l'id = "myId" à votre page principale, mais à la page dans l'iFrame. De cette façon, vous pouvez cibler le corps de la page iFrame avec un style différent de celui de votre page principale. Vous faites également référence au fichier CSS dans vos pages iFrame. Vous devez traiter la page chargée dans l'iFrame comme une page complètement indépendante. Si vous ne chargez que cette page dans un navigateur Web, a-t-elle le bon style?
mikeq
Je ne sais pas vraiment où se trouve la «page» car ce n'est pas la page entière que l'éditeur utilise. Merci pour votre aide, je pense que je comprends comment tout cela fonctionne non.
jd6699