Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to move an iFrame in the DOM without losing its state?

Take a look at this simple HTML:

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

Let's say I wanted to move the wraps so that the #wrap2 would be before the #wrap1. The iframes are polluted by JavaScript. I am aware of jQuery's .insertAfter() and .insertBefore(). However, when I use those, the iFrame loses all of its HTML, and JavaScript variables and events.

Lets say the following was the iFrame's 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> 

In the above code, the variable variableThatChanges would...change if the user clicked on the body. This variable, and the click event, should remain after the iFrame is moved (along with any other variables/events that have been started)

My question is the following: with JavaScript (with or without jQuery), how can I move the wrap nodes in the DOM (and their iframe childs) so that the iFrame's window stays the same, and the iFrame's events/variables/etc stay the same?

like image 464
JCOC611 Avatar asked Nov 29 '11 21:11

JCOC611


People also ask

How do you change the position of an iframe?

position: absolute; This will give the iframe a position relative to the wrapper and let it be positioned over the padding of the wrapper. top: 0 and left: 0 are used to position the iframe at the center of the container. width: 100% and height: 100% make the iframe take all of the wrapper's space.

Is there a better way than iframe?

Use the embed Tag as an Alternative to Iframe in HTML The embed tag is similar to the object tag, and it is used for the same purpose. We can embed various external resources in our web page using the embed tag. We can embed media like PDF, image, audio, video, and web pages.

Are iFrames bad practice?

Iframes Bring Security Risks. If you create an iframe, your site becomes vulnerable to cross-site attacks. You may get a submittable malicious web form, phishing your users' personal data. A malicious user can run a plug-in.

Is iframe going to be deprecated?

IFrames are not obsolete, but the reasons for using them are rare. Using IFrames to serve your own content creates a "wall" around accessing the content in that area. For crawlers like Google, It's not immediately clear that cotent in an iframe will be ranked as highly as if the content were simply part of the page.


2 Answers

It isn't possible to move an iframe from one place in the dom to another without it reloading.

Here is an example to show that even using native JavaScript the iFrames still reload: http://jsfiddle.net/pZ23B/

var wrap1 = document.getElementById('wrap1'); var wrap2 = document.getElementById('wrap2'); setTimeout(function(){     document.getElementsByTagName('body')[0].appendChild(wrap1); },10000); 
like image 186
Kevin B Avatar answered Oct 14 '22 18:10

Kevin B


This answer is related to the bounty by @djechlin

A lot of search on the w3/dom specs and didn't find anything final that specifically says that iframe should be reloaded while moving in the DOM tree, however I did find lots of references and comments in the webkit's trac/bugzilla/microsoft regarding different behavior changes over the years.

I hope someone will find anything specific regarding this issue, but for now here are my findings:

  1. According to Ryosuke Niwa - "That's the expected behavior".
  2. There was a "magic iframe" (webkit, 2010), but it was removed in 2012.
  3. According to MS - "iframe resources are freed when removed from the DOM". When you appendChild(node) of existing node - that node is first removed from the dom.
    Interesting thing here - IE<=8 didn't reload the iframe - this behavior is (somewhat) new (since IE>=9).
  4. According to Hallvord R. M. Steen comment, this is a quote from the iframe specs

    When an iframe element is inserted into a document that has a browsing context, the user agent must create a new browsing context, set the element's nested browsing context to the newly-created browsing context, and then process the iframe attributes for the "first time".

    This is the most close thing I found in the specs, however it's still require some interpretation (since when we move the iframe element in the DOM we don't really do a full remove, even if the browsers uses the node.removeChild method).

like image 43
Dekel Avatar answered Oct 14 '22 17:10

Dekel