अपने राज्य को खोए बिना डोम में iFrame कैसे स्थानांतरित करें?


93

इस सरल HTML पर एक नज़र डालें:

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

मान लीजिए कि मैं रैप को स्थानांतरित करना चाहता था ताकि #wrap2पहले हो #wrap1। Iframes जावास्क्रिप्ट द्वारा प्रदूषित हैं। मैं jQuery के के बारे में पता कर रहा हूँ .insertAfter()और .insertBefore()। हालाँकि, जब मैं उन का उपयोग करता हूं, तो iFrame अपने सभी HTML, और जावास्क्रिप्ट चर और घटनाओं को खो देता है।

आइए बताते हैं कि निम्नलिखित 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 स्थानांतरित होने के बाद भी रहना चाहिए (किसी भी अन्य चर / घटनाओं के साथ शुरू किया गया है)

मेरा प्रश्न निम्नलिखित है: जावास्क्रिप्ट के साथ (jQuery के साथ या बिना), मैं DOM (और उनके iframe childs) में रैप नोड्स को कैसे स्थानांतरित कर सकता हूं ताकि iFrame की विंडो समान रहे, और iFrame की घटनाएँ / चर / आदि रहें। वही?


पहले (लंबे समय पहले) पूछा -> stackoverflow.com/questions/2885504/… और stackoverflow.com/questions/3029871/…
Manse

वर्तमान बग मोज़िला के साथ उठाया ... bugzilla.mozilla.org/show_bug.cgi?id=254144
Manse

@ मानसेक: अन्य प्रश्न वास्तव में मदद नहीं करते ... लेकिन बग बहुत दिलचस्प है।
JCOC611

1
@SalmanA आप एक बच्चे को "माता-पिता" कैसे घुमाते हैं?
djechlin

1
@denodster वांछित प्रभाव वापस जब मैंने यह सवाल खोला था, तत्वों की एक सूची के क्रम को बदलने के लिए था, प्रत्येक inline-blockप्रदर्शन के साथ ... इस बिंदु पर, मैं एक सामान्य समाधान का अनुमान लगा रहा हूं (या प्रभावी रूप से यह कथन असंभव है) दूसरों के हित को देखते हुए, सबसे उपयुक्त होगा।
JCOC611

जवाबों:


46

इसके बिना डोम में एक स्थान से दूसरे स्थान पर पुनः लोड करना संभव नहीं है।

यहां यह दिखाने के लिए एक उदाहरण है कि देशी जावास्क्रिप्ट का उपयोग करते हुए भी iFrames अभी भी पुनः लोड होता है: 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

3
ठीक है, उदाहरण का उद्देश्य यह दिखाना है कि यहां तक ​​कि देशी जावास्क्रिप्ट का उपयोग करते हुए iFrames अभी भी पुनः लोड होता है।
केविन बी

ठीक है, वास्तव में, मुझे वास्तव में परवाह नहीं है कि क्या यह फिर से लोड करता है या नहीं, क्योंकि उनके स्थान हैं about:blank, लेकिन मैं जो परवाह करता हूं वह फ्रेम के अंदर की सामग्री को खो रहा है।
JCOC611

1
अगर यह फिर से लोड होता है, तो इससे आईफ्रेम के अंदर की सामग्री खो जाएगी। मुझे लगता है कि आप jquery का उपयोग करके इसे हिलाने से पहले iframe के अंदर की सामग्री को पकड़ सकते हैं, $("#iframeid").contents()लेकिन संग्रहीत जावास्क्रिप्ट डेटा नहीं मिलेगा, इसे iframe द्वारा मूल पृष्ठ पर भेजना होगा। (या मूल पृष्ठ से इसे हथियाना होगा। iframe)
केविन बी

1
DelightedD0D, बाउंटी को @djechlin द्वारा खोला गया था - "मुझे आश्चर्य है कि क्या यह अभी भी 2016 में सच है" यह देखने के लिए कि क्या इस मुद्दे के बारे में पिछले 5 वर्षों में कुछ भी बदल गया है। आप इन वर्षों के दौरान हुए परिवर्तनों के संबंध में मेरे उत्तर में सारांश की जाँच कर सकते हैं।
डेकेल

40

यह उत्तर @djechlin द्वारा इनाम से संबंधित है

डब्ल्यू 3 / डोम स्पेक्स पर बहुत सारी खोज और अंतिम रूप से ऐसा कुछ भी नहीं मिला, जो विशेष रूप से यह कहता हो कि डोम ट्री में चलते समय आइफ्रेम को फिर से लोड किया जाना चाहिए, हालांकि मुझे वेबकिट के ट्रैक / बगज़िला या माइक्रोसॉफ्ट में बहुत सारे संदर्भ और टिप्पणियां मिलीं विभिन्न व्यवहार वर्षों में बदलते हैं।

मुझे आशा है कि किसी को इस मुद्दे के बारे में कुछ विशेष मिलेगा, लेकिन अब यहाँ मेरे लिए निष्कर्ष हैं:

  1. Ryosuke Niwa के अनुसार - "यह अपेक्षित व्यवहार है"।
  2. "मैजिक आइफ्रेम" ( वेबकिट, 2010 ) था, लेकिन इसे 2012 में हटा दिया गया था ।
  3. MS के अनुसार - " DOM से हटाए जाने पर iframe संसाधनों को मुक्त कर दिया जाता है "। जब आप appendChild(node)मौजूदा नोड - कि nodeपहले डोम से हटा दिया जाता है।
    यहाँ दिलचस्प बात - IE<=8iframe को फिर से लोड नहीं किया - यह व्यवहार (कुछ) नया (तब से IE>=9) है।
  4. हॉलवार्ड आरएम स्टीन की टिप्पणी के अनुसार , यह आइफ्रेम स्पेक्स का एक उद्धरण है

    जब एक iframe तत्व एक दस्तावेज़ में डाला जाता है जिसमें ब्राउज़िंग संदर्भ होता है, तो उपयोगकर्ता एजेंट को एक नया ब्राउज़िंग संदर्भ बनाना होगा, तत्व के नेस्टेड ब्राउज़िंग प्रसंग को नव-निर्मित ब्राउज़िंग संदर्भ में सेट करना होगा और फिर iframe विशेषताओं को "पहली बार" संसाधित करना होगा। ”

    यह सबसे नज़दीकी चीज़ है जो मुझे ऐनक में मिली है, हालाँकि इसकी अभी भी कुछ व्याख्या की आवश्यकता है (क्योंकि जब हम iframeतत्व को DOM में स्थानांतरित करते हैं तो हम वास्तव में पूर्ण नहीं करते हैं remove, भले ही ब्राउज़र node.removeChildविधि का उपयोग करता हो )।


7
स्पष्टीकरण के साथ डाउनवॉटर के उत्तर की सराहना करेंगे।
डेकेल

14

जब भी एक iframe जोड़ा जाता है और इसमें src विशेषता लागू होती है, तो यह JS के माध्यम से एक छवि टैग बनाते समय एक लोड एक्शन के समान होता है। इसलिए जब आप हटाते हैं और फिर उन्हें जोड़ते हैं तो वे पूरी तरह से नई इकाइयाँ होती हैं और वे ताज़ा हो जाती हैं। इसका प्रकार window.location = window.locationएक पृष्ठ को पुनः लोड कैसे करेगा।

जिस तरह से मुझे पता है कि पुनरावृत्ति iframesसीएसएस के माध्यम से है। यहाँ एक उदाहरण है जिसे मैंने एक साथ दिखाया है ताकि इसे संभालने का एक तरीका मिल सके flex-box: https://jsfiddle.net/3g73sz3k/15/

मूल विचार एक flex-boxआवरण बनाना है और फिर प्रत्येक iframe आवरण पर आदेश विशेषता का उपयोग करते हुए iframes के लिए एक विशिष्ट क्रम को परिभाषित करना है।

<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 fiddle में देख सकते हैं कि ये orderस्टाइल flipबटन को सरल बनाने के लिए इनलाइन हैं इसलिए रोटेट करें iframes

मैंने इस StackOverflow प्रश्न से हल निकाला: केवल सीएसएस के साथ DIV की स्थिति

उम्मीद है की वो मदद करदे।


1
1 पैराग्राफ के लिए बाउंटी और यह बताना कि यह नई संस्था बनाने और बनाने के लिए समान है। सीएसएस नहीं: पी
djechlin

इतना सरल और प्रभावी! आपका बहुत धन्यवाद!
स्टेन

8

यदि आपने पृष्ठ पर iFrame बनाया है और बस इसे स्थानांतरित करने की आवश्यकता है तो बाद में इस दृष्टिकोण को आज़माएं:

शरीर को iFrame अप्लाई करें और जहाँ आप चाहते हैं वहाँ iFrame लगाने के लिए एक उच्च z-index और ऊपर, बाएँ, चौड़ाई, ऊँचाई का उपयोग करें।

यहां तक ​​कि सीएसएस जूम फिर से लोड किए बिना शरीर पर काम करता है जो भयानक है!

मैं अपने "विजेट" के लिए दो राज्यों को बनाए रखता हूं और यह इस विधि का उपयोग करके या तो डोम में या शरीर में इंजेक्शन लगाया जाता है।

यह तब उपयोगी है जब अन्य सामग्री या लाइब्रेरी आपके आईफ्रेम को स्क्वैश या स्क्वैश करेगी।

बूम!


5

दुर्भाग्य से, parentNodeएक HTML DOM तत्व की संपत्ति केवल-पढ़ने के लिए है। आप बेशक, आइफ्रेम के पदों को समायोजित कर सकते हैं, लेकिन आप डोम में अपना स्थान नहीं बदल सकते हैं और अपने राज्यों को संरक्षित कर सकते हैं।

इस jsfiddle मैं बनाया है कि एक अच्छा परीक्षण बिस्तर प्रदान करता है देखें। http://jsfiddle.net/RpHTj/1/

मान को टॉगल करने के लिए बॉक्स पर क्लिक करें। जावास्क्रिप्ट को चलाने के लिए "चाल" पर क्लिक करें।


4

यह प्रश्न बहुत पुराना है ... लेकिन मैंने इसे पुनः लोड किए बिना एक iframe को स्थानांतरित करने का एक तरीका ढूंढ लिया। केवल सीएसएस। मैं कैमरा धाराओं के साथ कई iframes है, मैं पसंद नहीं है जब वे पुनः लोड जब मैं उन्हें स्वैप। इसलिए मैंने फ्लोट, स्थिति: निरपेक्ष, और कुछ डमी ब्लॉकों के संयोजन का उपयोग किया ताकि उन्हें फिर से लोड किए बिना उन्हें स्थानांतरित किया जा सके और मांग पर वांछित लेआउट (आकार बदलना और सभी) हो।


1
एकमात्र व्यवहार्य विकल्प की तरह लगता है। आपको अपना पूरा समाधान पोस्ट करना चाहिए! दूसरों को आरंभ करने के लिए कम से कम कुछ मूल कोड। धन्यवाद!
JCOC611

1

इस प्रश्न पर दिए गए इनाम @djechlin के जवाब में, मैंने @ मैट-एच द्वारा पोस्ट की गई 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 का उपयोग कर रहे हैं, तो आप अपने माता-पिता को पोस्टमैसेज के माध्यम से iframe के साथ संवाद करने की अनुमति देने के लिए कुछ जावास्क्रिप्ट बना सकते हैं

वहां से, आप राज्य परिवर्तनों को रिकॉर्ड करने के लिए iframe के अंदर लॉगिन का निर्माण कर सकते हैं, और डोम को स्थानांतरित करने से पहले, अनुरोध कर सकते हैं कि एक json ऑब्जेक्ट के रूप में।

एक बार स्थानांतरित होने पर, iframe पुनः लोड होगा, आप राज्य डेटा को iframe में पास कर सकते हैं और iframe सुनकर डेटा को पिछली स्थिति में वापस भेज सकते हैं।


दी, यह बहुत सारा कोड है, आपको लगता है कि आप सभी डेटा को नियंत्रित करते हैं जो फ्रेम में प्रदर्शित होंगे, और फिर भी तकनीकी रूप से "डोम में चलते समय राज्य को बनाए नहीं रखते"
ड्रू मेजर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.