web-dev-qa-db-fra.com

Iframes imbriquées, AKA Iframe Inception

En utilisant jQuery, j'essaie d'accéder à div id = "element".

<body>
    <iframe id="uploads">
        <iframe>
            <div id="element">...</div>
        </iframe>
    </iframe>
</body>

Tous les iframes sont sur le même domaine sans problèmes www/non-www.

J'ai sélectionné avec succès des éléments dans le premier iframe mais pas le second iframe imbriqué.

J'ai essayé quelques choses, c'est la plus récente (et une tentative assez désespérée).

var iframe = jQuery('#upload').contents();
var iframeInner = jQuery(iframe).find('iframe').contents();
var iframeContent = jQuery(iframeInner).contents().find('#element');

// iframeContent is null

Edit: Pour éliminer un problème de minutage, j’ai utilisé un événement de clic et attendu un certain temps.

jQuery().click(function(){
   var iframe = jQuery('#upload').contents().find('iframe');
   console.log(iframe.find('#element')); // [] null
});

Des idées? Merci.

Mise à jour: je peux sélectionner le deuxième iframe comme si ...

var iframe = jQuery('#upload').contents().find('iframe');

Le problème semble maintenant être que le src est vide car l’iframe est généré avec javascript. Donc, l'iframe est sélectionné mais la longueur du contenu est 0.

42
Ian Brindley

Le code que vous avez fourni ne fonctionnera pas car l'élément <iframe> Doit avoir une propriété "src", comme:

<iframe id="uploads" src="http://domain/page.html"></iframe>

Vous pouvez utiliser .contents() pour obtenir le contenu:

$('#uploads).contents() vous donnera accès à la deuxième iframe, mais si cette iframe est "INSIDE", le document http://domain/page.html est alors chargé par la #uploads iframe.

Pour vérifier si j'ai raison, j’ai créé 3 fichiers html nommés main.html, iframe.html et noframe.html, puis sélectionné l’élément div # avec les éléments suivants:

$('#uploads').contents().find('iframe').contents().find('#element');

Il y aura un délai dans lequel l'élément ne sera pas disponible car vous devez attendre que l'iframe charge la ressource. De plus, tous les iframes doivent appartenir au même domaine.

J'espère que cela t'aides ...

Voici le code HTML des 3 fichiers que j'ai utilisés (remplacez les attributs "src" par votre domaine et votre URL):

main.html

<!DOCTYPE HTML>
<html>
<head>
    <meta charset="utf-8">
    <title>main.html example</title>

    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

    <script>
        $(function () {
            console.log( $('#uploads').contents().find('iframe').contents().find('#element') ); // nothing at first

            setTimeout( function () {
                console.log( $('#uploads').contents().find('iframe').contents().find('#element') ); // wait and you'll have it
            }, 2000 );

        });
    </script>
</head>
<body>
    <iframe id="uploads" src="http://192.168.1.70/test/iframe.html"></iframe>
</body>

iframe.html

<!DOCTYPE HTML>
<html>
<head>
    <meta charset="utf-8">
    <title>iframe.html example</title>
</head>
<body>
    <iframe src="http://192.168.1.70/test/noframe.html"></iframe>
</body>

noframe.html

<!DOCTYPE HTML>
<html>
<head>
    <meta charset="utf-8">
    <title>noframe.html example</title>
</head>
<body>
    <div id="element">some content</div>
</body>
59
Carlos Castillo

var iframeInner = jQuery(iframe).find('iframe').contents();

var iframeContent = jQuery(iframeInner).contents().find('#element');

iframeInner contient des éléments de

<div id="element">other markup goes here</div> 

et iframeContent trouvera pour les éléments qui sont à l'intérieur de

 <div id="element">other markup goes here</div> 

(find ne cherche pas l'élément en cours) c'est pourquoi il renvoie null.

13
Bhargavi Gunda

Hey, j'ai quelque chose qui semble faire ce que tu veux faire. Cela implique des copies sales mais fonctionne. Vous pouvez trouver le code de travail ici

Donc, voici le fichier HTML principal:

<!DOCTYPE html>
<html>
<head>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

    <script type="text/javascript">
        $(document).ready(function(){
            Iframe = $('#frame1');

            Iframe.on('load', function(){
                IframeInner = Iframe.contents().find('iframe');

                IframeInnerClone = IframeInner.clone();

                IframeInnerClone.insertAfter($('#insertIframeAfter')).css({display:'none'});

                IframeInnerClone.on('load', function(){
                    IframeContents = IframeInner.contents();

                    YourNestedEl = IframeContents.find('div');

                    $('<div>Yeepi! I can even insert stuff!</div>').insertAfter(YourNestedEl)
                });
            });
        });
    </script>
</head>
<body>
    <div id="insertIframeAfter">Hello!!!!</div>
    <iframe id="frame1" src="Test_Iframe.html">

    </iframe>
</body>
</html>

Comme vous pouvez le constater, une fois le premier Iframe chargé, je récupère le deuxième et le clone. Je le réinsère ensuite dans le domaine pour pouvoir accéder à l'événement onload. Une fois celui-ci chargé, je récupère le contenu d'un fichier non cloné (il doit également avoir été chargé, car ils utilisent le même code src). Vous pouvez ensuite faire ce que vous voulez avec le contenu.

Voici le fichier Test_Iframe.html:

<!DOCTYPE html>
<html>
<head>
</head>
<body>
    <div>Test_Iframe</div>
    <iframe src="Test_Iframe2.html">
    </iframe>
</body>
</html>

et le fichier Test_Iframe2.html:

<!DOCTYPE html>
<html>
<head>
</head>
<body>
    <div>I am the second nested iframe</div>
</body>
</html>
4

Vous devez utiliser la méthode live pour les éléments rendus ultérieurement, tels que colorbox, champs cachés ou iframe.

$(".inverter-value").live("change",function() {
     elem = this
    $.ajax({
      url: '/main/invertor_attribute/',
      type: 'POST',
      aysnc: false,
      data: {id: $(this).val() },
      success: function(data){
       // code
      },
      dataType: 'html'
    });
  });
1
Tauqeer Ahmad

Vous avez probablement un problème de timing. Votre recommandation document.ready se déclenche probablement avant le chargement du deuxième iFrame. Vous n'avez pas assez d'informations pour aider beaucoup plus loin, mais laissez-nous savoir si cela semble être le problème possible.

1
Carntel

Je suppose que votre problème est que jQuery n'est pas chargé dans vos iframes.

L'approche la plus sûre consiste à utiliser des méthodes pures basées sur le DOM pour analyser votre contenu.

Sinon, commencez par jQuery, puis une fois dans vos iframes, testez une fois si typeof window.jQuery == 'undefined', si c'est vrai, jQuery n'est pas activé à l'intérieur de celui-ci et effectue un repli sur une méthode basée sur DOM.

0
Mathieu Amiot

Je pense que la meilleure façon d'atteindre votre div:

var your_element=$('iframe#uploads').children('iframe').children('div#element');

Ça devrait bien marcher.

0
csaron92

Si le navigateur prend en charge l'iframe, les DOM à l'intérieur de l'iframe proviennent de l'attribut src de la balise respective. Le contenu de la balise iframe est utilisé comme mécanisme de secours lorsque le navigateur ne prend pas en charge la balise iframe.

Réf.: http://www.w3schools.com/tags/tag_iframe.asp

0
Gladwin Burboz