状態を失わずにDOMでiFrameを移動する方法は?


93

この単純なHTMLを見てください。

<div id="wrap1">
  <iframe id="iframe1"></iframe>
</div>
<div id="warp2">
  <iframe id="iframe2"></iframe>
</div>

#wrap2がの前になるようにラップを移動したいとし#wrap1ます。iframeはJavaScriptによって汚染されています。私はjQuery .insertAfter()とを知ってい.insertBefore()ます。ただし、これらを使用すると、iFrameはHTML、JavaScript変数、およびイベントをすべて失います。

以下がiFrameのHTMLだとします。

<html>
  <head>
    <script type="text/javascript" src="jquery.js"></script>
    <script type="text/javascript">
      // The variable below would change on click
      // This represents changes on variables after the code is loaded
      // These changes should remain after the iFrame is moved
      variableThatChanges = false;
      $(function(){
        $("body").click(function(){ 
          variableThatChanges = true; 
        });
      });
    </script>
  </head>
  <body>
    <div id='anything'>Illustrative Example</div>
  </body>
</html>

上記のコードではvariableThatChanges、ユーザーが本文をクリックすると、変数が変更されます。この変数とクリックイベントは、iFrameが移動された後も(開始されている他の変数/イベントとともに)残っている必要があります。

私の質問は次のとおりです:JavaScript(jQueryありまたはなし)で、DOM(およびそのiframeの子)でラップノードを移動して、iFrameのウィンドウが同じままで、iFrameのイベント/変数/ etcが同じ?



Mozillaで発生した現在のバグ... bugzilla.mozilla.org/show_bug.cgi?id=254144
Manse

@ManseUK:他の質問は本当に役に立ちませんでした...しかし、バグはかなり興味深いです。
JCOC611

1
@SalmanAどのように親を子の「周り」に移動しますか?
djechlin 2016年

1
@denodsterこの質問を開いたときの望ましい効果の方法は、要素のリストの順序を変更することでした。それぞれがinline-block表示されます...この時点で、私は一般的な解決策(または事実上、そのようなことは不可能であるという声明)を推測しています他人の関心を考えると、最も適切でしょう。
JCOC611

回答:


46

再読み込みしないと、iframeをdom内のある場所から別の場所に移動することはできません。

ここでも、ネイティブのJavaScriptにまだリロードのiFrameを使用していることを示すための例は次のとおりです。 http://jsfiddle.net/pZ23B/

var wrap1 = document.getElementById('wrap1');
var wrap2 = document.getElementById('wrap2');
setTimeout(function(){
    document.getElementsByTagName('body')[0].appendChild(wrap1);
},10000);

4
まあ、iFrameがリロードする場合、それはオプションではありません。
JCOC611

3
この例の目的は、ネイティブJavaScriptを使用してもiFrameがリロードされることを示すことです。
ケビンB

まあ、実際にはabout:blank、その場所はなの​​で、リロードするかどうかは気にしませんが、気になるのはフレーム内のコンテンツを失うことです。
JCOC611 2011年

1
リロードすると、iframe内のコンテンツが失われます。jqueryを使用して移動する前にiframe内のコンテンツを取得できると思いますが、$("#iframeid").contents()JavaScriptデータが格納されないため、iframeによって親ページに送信する必要があります(または親ページから取得する必要がありますiframe)
ケビンB

1
DelightedD0D、報奨金は@djechlinによって開かれました-この問題に関して過去5年間に何か変更があったかどうかを確認するために、「2016年もこれは本当ですか?」これらの年の変化に関する私の回答の要約を確認できます。
デケル

40

この回答は@djechlinの賞金に関連しています

w3 / dom仕様をたくさん検索しましたが、DOMツリー内を移動中にiframeをリロードする必要があると具体的に言っている最終的な結果は見つかりませんでしたが、Webkitのtrac / bugzilla / microsoftで多くの参照とコメントを見つけましたさまざまな行動が長年にわたって変化します。

私は誰かがこの問題に関して何か特定のものを見つけることを望みますが、今のところここに私の発見があります:

  1. 丹羽涼介氏によると「これが予想される行動だ」。
  2. 「magic iframe」(webkit、2010)がありましたが、2012年削除されました
  3. MSによると-「iframeリソースはDOMから削除されると解放されます」。いつappendChild(node)-既存のノードのnode最初のDOMから削除されます。
    ここで興味深いのIE<=8は-iframeをリロードしなかった-この動作は(やや)新しい(からIE>=9)です。
  4. Hallvord RM Steenのコメントによると、これはiframe仕様からの引用です

    ブラウジングコンテキストを持つドキュメントにiframe要素が挿入されると、ユーザーエージェントは新しいブラウジングコンテキストを作成し、要素のネストされたブラウジングコンテキストを新しく作成されたブラウジングコンテキストに設定して、iframe属性を「初めて」処理する必要があります。 "

    これは私が仕様で見つけた最も近いものですが、それでもある程度の解釈が必要です(iframeDOMで要素を移動するときremove、ブラウザがnode.removeChildメソッドを使用していても、実際には完全なを実行しないため)。


7
説明付きダウンボッターからの返信をいただければ幸いです。
デケル

14

iframeが追加され、src属性が適用されている場合は常に、JSを介してイメージタグを作成する場合と同様に、ロードアクションが実行されます。したがって、削除して追加すると、それらは完全に新しいエンティティであり、更新されます。その種類のwindow.location = window.locationページをリロードします。

私が再配置するために知っている唯一の方法iframesは、CSS経由です。これをまとめた例を次に示しますflex-boxhttps : //jsfiddle.net/3g73sz3k/15/

基本的な考え方は、flex-boxラッパーを作成し、各iframeラッパーのorder属性を使用してiframeの特定の順序を定義することです。

<style>
  .container{
    display: flex;
    flex-direction: column;
  }
</style>
<div class="container">
  <div id="wrap1" style="order: 0" class="iframe-wrapper">
    <iframe id="iframe1" src="https://google.com"></iframe>
  </div>
  <div id="warp2" style="order: 1" class="iframe-wrapper">
    <iframe id="iframe2" src="https://bing.com"></iframe>
  </div>
</div>

JSフィドルでわかるように、これらのorderスタイルはflipボタンを単純化するためにインラインなので、を回転させiframesます。

このStackOverflowの質問からソリューションを入手しました:DIV位置をCSSのみと交換

お役に立てば幸いです。


1
第1パラグラフの賞金と説明はimgに似ており、新しいエンティティを作成します。CSSではありません:P
djechlin

とてもシンプルで効果的です!どうもありがとうございました!
Stan

8

ページ上にiFrameを作成し、後でその位置を移動する必要がある場合は、次の方法を試してください。

本体にiFrameを追加し、高いz-indexとtop、left、width、heightを使用して、iFrameを目的の場所に配置します。

CSSズームでさえ、リロードせずに本体で機能します。

私は「ウィジェット」の2つの状態を維持しており、DOMの適切な場所に挿入されるか、このメソッドを使用して本文に挿入されます。

これは、他のコンテンツまたはライブラリがiFrameを圧縮または圧縮する場合に役立ちます。

ブーム!


5

残念ながら、parentNodeHTML DOM要素のプロパティは読み取り専用です。もちろん、iframeの位置を調整することはできますが、DOMでのiframeの位置を変更して状態を保持することはできません。

優れたテストベッドを提供する、私が作成したこのjsfiddleを参照してください。http://jsfiddle.net/RpHTj/1/

ボックスをクリックして値を切り替えます。「移動」をクリックしてJavaScriptを実行します。


4

この質問はかなり古いです...しかし、リロードせずにiframeを移動する方法を見つけました。CSSのみ。私はカメラストリームを備えた複数のiframeを持っていますが、それらを交換したときに再ロードするのは好きではありません。したがって、float、position:absolute、およびいくつかのダミーブロックの組み合わせを使用して、リロードせずにオンデマンドで希望のレイアウト(サイズ変更とすべて)をせずに移動しました。


1
唯一の実行可能なオプションのように聞こえます。思いついた完全な解決策を投稿してください!他の人が始めるための少なくともいくつかの基本的なコード。ありがとう!
JCOC611 2016年

1

この質問に寄せられた報奨金@djechlinに応えて、@ matt-hによって投稿されたjsfiddleを分岐し、これはまだ不可能であるという結論に達しました。

http://jsfiddle.net/gr3wo9u6/

//this does not work, the frames reload when appended back to the DOM
function swapFrames() {
    var w1 = document.getElementById('wrap1');
    var w2 = document.getElementById('wrap2');
    var f1 = w1.querySelector('iframe');
    var f2 = w2.querySelector('iframe');

    w1.removeChild(f1);
    w2.removeChild(f2);
    w1.appendChild(f2);
    w2.appendChild(f1);
    //f1.parentNode = w2;
    //f2.parentNode = w1;

    //alert(f1.parentNode.id);
}

0

制御するページにアクセスするためにiframeを使用している場合は、javascriptを作成して、親がpostMessageを介してiframeと通信できるようにすることができます。

そこから、iframe内にログインを作成して状態の変化を記録し、domを移動する前に、jsonオブジェクトとして要求することができます。

移動すると、iframeがリロードされ、状態データをiframeに渡し、iframeがデータを解析して以前の状態に戻すことができます。


確かに、これは多くのコードであり、フレームに表示されるすべてのデータを制御し、技術的には「DOM内を移動するときに状態を維持しない」と想定しています
Drew Major
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.