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


95

이 간단한 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 자식)의 랩 노드를 어떻게 이동할 수 있습니까? 같은?



Mozilla로 발생한 현재 버그 ... bugzilla.mozilla.org/show_bug.cgi?id=254144
— Manse

@ManseUK : 다른 질문은별로 도움이되지 않았지만 버그는 꽤 흥미 롭습니다.
— JCOC611

1
@SalmanA 어떻게 부모를 아이 "주위"로 이동합니까?
— djechlin

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
글쎄, iFrames가 다시로드되면 옵션이 아닙니다.
— JCOC611 2011

3
예의 목적은 네이티브 JavaScript를 사용하더라도 iFrame이 여전히 다시로드된다는 것을 보여주는 것입니다.
— Kevin B

글쎄, 사실, 나는 그것이 다시로드되는지 여부는 신경 쓰지 않는다. 그들의 위치는 about:blank.하지만 내가 신경 쓰는 것은 프레임 내부의 내용을 잃는 것입니다.
— JCOC611 2011

1
다시로드되면 iframe 내부의 콘텐츠가 손실됩니다. jquery를 사용하여 이동하기 전에 iframe 내부의 내용을 가져올 수 $("#iframeid").contents()있지만 저장된 javascript 데이터를 얻지 못하며 iframe에 의해 상위 페이지로 전송되어야합니다 (또는 상위 페이지에서 가져와야합니다. iframe)
— Kevin B

1
DelightedD0D, 현상금은 @djechlin에 의해 개설되었습니다. "2016 년에도 이것이 사실인지 궁금합니다."이 문제와 관련하여 지난 5 년 동안 변경된 사항이 있는지 확인합니다. 이 기간 동안의 변경 사항에 대한 내 답변에서 요약을 확인할 수 있습니다.
— Dekel

41

이 답변은 @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메서드를 사용하더라도 실제로 전체 작업을 수행하지 않기 때문에 ).


7
설명과 함께 반대 투표자의 답변을 주시면 감사하겠습니다.
— Dekel

14

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로만 바꿉니다 .

도움이되기를 바랍니다.


1
첫 번째 단락에 대한 현상금 및 img 및 새 엔티티 생성과 유사 함을 설명합니다. 하지 CSS : P
— djechlin

매우 간단하고 효과적입니다! 정말 고마워!
— Stan

8

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

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

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

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

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

팔!


5

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

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

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


4

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


1
유일한 실행 가능한 옵션처럼 들립니다. 당신이 생각 해낸 전체 솔루션을 게시해야합니다! 다른 사람들을 시작하기위한 최소한의 기본 코드. 감사!
— JCOC611

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을 사용하여 제어하는 ​​페이지에 액세스하는 경우 부모가 postMessage를 통해 iframe과 통신 할 수 있도록 자바 스크립트를 만들 수 있습니다.

거기에서 상태 변경을 기록하기 위해 iframe 내부에 로그인을 빌드하고 dom을 이동하기 전에 json 객체로 요청할 수 있습니다.

이동되면 iframe이 다시로드되고 상태 데이터를 iframe으로 전달할 수 있으며 iframe 수신 대기자는 데이터를 다시 이전 상태로 구문 분석 할 수 있습니다.


물론, 이것은 많은 코드이며, 프레임에 표시 될 모든 데이터를 제어하고 기술적으로 "DOM에서 이동할 때 상태를 유지"하지
— Drew Major
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.