[javascript] 상태를 잃지 않고 DOM에서 iFrame을 이동하는 방법은 무엇입니까?

이 간단한 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 포함 또는 제외)를 사용하여 iFrame의 창이 동일하게 유지되고 iFrame의 이벤트 / 변수 / 등이 유지되도록 DOM (및 iframe 자식)의 랩 노드를 어떻게 이동할 수 있습니까? 같은?



답변

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);


답변

이 답변은 @djechlin의 현상금과 관련이 있습니다.

w3 / dom 사양에 대한 많은 검색과 DOM 트리에서 이동하는 동안 iframe을 다시로드해야한다고 구체적으로 말하는 최종 항목을 찾지 못했지만 웹킷의 trac / bugzilla / microsoft에서 많은 참조와 주석을 찾았습니다. 수년에 걸쳐 다른 행동 변화.

누군가가이 문제와 관련하여 구체적인 내용을 찾을 수 있기를 바라지 만 지금은 여기에 내 결과가 있습니다.

  1. 니와 료스케 에 따르면 – “그것이 예상되는 동작입니다”.
  2. “magic iframe”( 웹킷, 2010 )이 있었지만 2012 년제거되었습니다 .
  3. MS에 따르면 ” iframe 리소스는 DOM에서 제거되면 해제됩니다 “. 때 appendChild(node)– 기존 노드의 node첫 번째 DOM에서 제거됩니다.
    여기서 재미있는 것은 – IE<=8iframe을 다시로드하지 않았다 -이 동작 입니다 (다소) 새로운 (이후 IE>=9).
  4. Hallvord RM Steen 의견 에 따르면 이것은 iframe 사양 에서 인용 한 것입니다.

    iframe 요소가 브라우징 컨텍스트가있는 문서에 삽입되면 사용자 에이전트는 새 브라우징 컨텍스트를 생성하고 요소의 중첩 브라우징 컨텍스트를 새로 생성 된 브라우징 컨텍스트로 설정 한 다음 “처음으로 iframe 속성을 처리해야합니다. “ .

    이것은 내가 스펙에서 찾은 가장 가까운 것이지만 여전히 약간의 해석이 필요 iframe합니다 (DOM 에서 요소를 이동할 때 remove브라우저가 node.removeChild메서드를 사용하더라도 실제로 전체 작업을 수행하지 않기 때문에 ).


답변

iframe이 추가되고 src 속성이 적용될 때마다 JS를 통해 이미지 태그를 만들 때와 비슷하게로드 작업을 실행합니다. 따라서 제거하고 추가하면 완전히 새로운 엔티티이며 새로 고쳐집니다. window.location = window.location페이지를 다시로드하는 방법 입니다.

재배치하는 유일한 방법 iframes은 CSS를 이용하는 것입니다. 다음은이를 처리하는 한 가지 방법을 보여주는 예제입니다 flex-box.
https://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로만 바꿉니다 .

도움이되기를 바랍니다.


답변

페이지에 iFrame을 만들고 나중에 위치를 이동해야하는 경우 다음 방법을 시도해보십시오.

iFrame을 본문에 추가하고 높은 Z- 색인과 상단, 왼쪽, 너비, 높이를 사용하여 원하는 위치에 iFrame을 배치합니다.

CSS 확대 / 축소도 다시로드하지 않고도 본문에서 작동합니다.

나는 내 “위젯”에 대해 두 가지 상태를 유지하며이 방법을 사용하여 DOM 또는 본문에 삽입됩니다.

다른 콘텐츠 나 라이브러리가 iFrame을 찌그러 뜨리거나 찌그러 뜨리는 경우 유용합니다.

팔!


답변

불행히도 parentNode HTML DOM 요소 속성은 읽기 전용입니다. 물론 iframe의 위치를 ​​조정할 수 있지만 DOM에서 위치를 변경하고 상태를 유지할 수는 없습니다.

좋은 테스트 베드를 제공하는이 jsfiddle을 참조하십시오. http://jsfiddle.net/RpHTj/1/

상자를 클릭하여 값을 전환하십시오. 자바 스크립트를 실행하려면 “이동”을 클릭하십시오.


답변

이 질문은 꽤 오래되었지만 다시로드하지 않고 iframe을 이동하는 방법을 찾았습니다. CSS 만. 카메라 스트림이있는 iframe이 여러 개 있는데 스왑 할 때 다시로드 할 때 마음에 들지 않습니다. 그래서 저는 float, position : absolute 및 일부 더미 블록의 조합을 사용하여 다시로드하지 않고 원하는 레이아웃 (크기 조정 및 모두)없이 이동했습니다.


답변

이 질문에 대한 현상금 @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);
}