IFRAME लोडिंग समाप्त होने पर जावास्क्रिप्ट कॉलबैक?


147

जब IFRAME ने लोडिंग पूरी कर ली हो, तो मुझे कॉलबैक निष्पादित करना होगा। IFRAME की सामग्री पर मेरा कोई नियंत्रण नहीं है, इसलिए मैं वहां से कॉलबैक को फायर नहीं कर सकता।

यह IFRAME प्रोग्रामेटिक रूप से बनाया गया है, और मुझे कॉलबैक में एक चर के रूप में इसके डेटा को पास करने की आवश्यकता है, साथ ही साथ iframe को नष्ट करना होगा।

कोई विचार?

संपादित करें:

यहाँ अब मेरे पास क्या है:

function xssRequest(url, callback)
{
    var iFrameObj = document.createElement('IFRAME');
    iFrameObj.src = url;            
    document.body.appendChild(iFrameObj);   

    $(iFrameObj).load(function() 
    {
        document.body.removeChild(iFrameObj);
        callback(iFrameObj.innerHTML);
    });
}

IFrame लोड होने से पहले यह कॉलबैक करता है, इसलिए कॉलबैक में कोई डेटा नहीं है।


1
मुझे लगता है कि आप iframe पर ईवेंट हैंडलर संलग्न नहीं करना चाहते हैं, लेकिन यह सामग्री विंडो है।
bobwienholt

1
समस्या क्रॉस-डोमेन अनुरोध है। यदि iframe किसी अन्य डोमेन से है तो आप ऐसा नहीं कर सकते
विक्टर

वास्तव में, iframe ऑब्जेक्ट पर एक लोड ईवेंट है जो हर बार फायर करता है यदि iframe एक दस्तावेज़ लोड करना समाप्त करता है, अन्यथा, आपको हर लोड के बाद विंडो को हुक करने की आवश्यकता होगी
जुआन मेंडेस

यह भी देखें stackoverflow.com/questions/205087/...
ripper234

मेरा जवाब यहाँ देखें: stackoverflow.com/a/36155560/3894981
dude

जवाबों:


49

सबसे पहले, फ़ंक्शन नाम xssRequest द्वारा जा रहा है, ऐसा लगता है कि आप क्रॉस साइट अनुरोध की कोशिश कर रहे हैं - जो कि यदि सही है, तो आप iframe की सामग्री को पढ़ने में सक्षम नहीं होंगे।

दूसरी तरफ, अगर iframe का URL आपके डोमेन पर है, तो आप शरीर तक पहुँच सकते हैं, लेकिन मैंने पाया है कि अगर मैं iframe को हटाने के लिए एक टाइमआउट का उपयोग करता हूँ तो कॉलबैक ठीक काम करता है:

// possibly excessive use of jQuery - but I've got a live working example in production
$('#myUniqueID').load(function () {
  if (typeof callback == 'function') {
    callback($('body', this.contentWindow.document).html());
  }
  setTimeout(function () {$('#frameId').remove();}, 50);
});

4
आप के $('body', this.contentWindow.document).html()साथ बदल सकते हैंthis.contentDocument.body.outerHTML
सैम Soffes

12
किसी भी विचार कैसे jQuery के बिना यह करने के लिए?
devios1

6
JQuery 3.0 के रूप में, loadचला गया है। कृपया .on('load', function() { ... })इसके बजाय उपयोग करें ।
डॉपेलगैंगर

36

मैं jQuery का उपयोग कर रहा हूं और आश्चर्यजनक रूप से यह लोड करने के लिए लगता है जैसा कि मैंने अभी परीक्षण किया है और एक भारी पृष्ठ लोड किया है और मुझे कुछ सेकंड के लिए अलर्ट नहीं मिला जब तक कि मैंने iframe लोड नहीं देखा:

$('#the_iframe').load(function(){
    alert('loaded!');
});

इसलिए यदि आप jQuery का उपयोग नहीं करना चाहते हैं तो उनके स्रोत कोड पर एक नज़र डालें और देखें कि क्या यह फ़ंक्शन iframe DOM तत्वों के साथ अलग तरह से व्यवहार करता है, मैं बाद में इसे स्वयं देखूंगा क्योंकि मैं यहाँ दिलचस्पी रखता हूं और पोस्ट करता हूं। इसके अलावा, मैंने केवल नवीनतम क्रोम में परीक्षण किया।


मैंने देखा कि आपने शुद्ध जावास्क्रिप्ट के साथ DOM तत्व बनाया है और फिर उस चर को jQuery को चयनकर्ता के रूप में पारित किया है, शायद इसीलिए आप कोड काम नहीं कर रहे हैं?
नव

12
JQuery 3.0 के रूप में, loadचला गया है। कृपया .on('load', function() { ... })इसके बजाय उपयोग करें ।
डॉपेलगैंगर

8

आपके iframe का आंतरिक HTML रिक्त है क्योंकि आपके iframe टैग को मूल दस्तावेज़ में कोई सामग्री नहीं मिलती है। Iframe की src विशेषता द्वारा संदर्भित पृष्ठ से सामग्री प्राप्त करने के लिए, आपको iframe की सामग्रीDocument संपत्ति तक पहुंचने की आवश्यकता है। यदि एक अलग डोमेन से src है, तो एक अपवाद को फेंक दिया जाएगा। यह एक सुरक्षा सुविधा है जो आपको किसी और के पेज पर मनमाने ढंग से जावास्क्रिप्ट को निष्पादित करने से रोकती है, जो क्रॉस-साइट स्क्रिप्टिंग भेद्यता पैदा करेगी। यहाँ कुछ उदाहरण कोड है जो दिखाता है कि मैं किस बारे में बात कर रहा हूँ:

<script src="http://prototypejs.org/assets/2009/8/31/prototype.js" type="text/javascript"></script>

<h1>Parent</h1>

<script type="text/javascript">
function on_load(iframe) {
  try {
    // Displays the first 50 chars in the innerHTML of the
    // body of the page that the iframe is showing.
    // EDIT 2012-04-17: for wider support, fallback to contentWindow.document
    var doc = iframe.contentDocument || iframe.contentWindow.document;
    alert(doc.body.innerHTML.substring(0, 50));
  } catch (e) {
    // This can happen if the src of the iframe is
    // on another domain
    alert('exception: ' + e);
  }
}
</script>
<iframe id="child" src="iframe_content.html" onload="on_load(this)"></iframe>

उदाहरण को आगे बढ़ाने के लिए, iframe की सामग्री के रूप में इसका उपयोग करने का प्रयास करें:

<h1>Child</h1>

<a href="http://www.google.com/">Google</a>

<p>Use the preceeding link to change the src of the iframe
to see what happens when the src domain is different from
that of the parent page</p>

1
contentDocument संपत्ति IE 7 और शायद अधिक IE के द्वारा समर्थित नहीं है, IE से निपटने का तरीका विंडो ['iframeid'] है। दस्तावेज़ या वास्तव में एक ही window.frames ['iframeid'] है। दस्तावेज़ प्रमाण यहाँ डेवलपर देखें। mozilla.org/en/…
ओल्गा

7

मुझे ऐसे मामलों में ऐसा करना पड़ा है, जहां डॉक्स और pdfs जैसे दस्तावेज़ों को iframe पर स्ट्रीम किया जा रहा है और एक समाधान मिला है जो बहुत अच्छा काम करता है। कुंजी onreadystatechangediframe पर ईवेंट को संभाल रही है ।

कहते हैं कि आपके फ़्रेम का नाम "myIframe" है। अपने कोड स्टार्टअप में पहले कहीं (मैं iframe के बाद किसी भी जगह इनलाइन करता हूं) इवेंट हैंडलर को पंजीकृत करने के लिए कुछ इस तरह से जोड़ें:

document.getElementById('myIframe').onreadystatechange = MyIframeReadyStateChanged;

मैं iframe पर एक onreadystatechage विशेषता का उपयोग करने में सक्षम नहीं था, मुझे याद नहीं है कि क्यों, लेकिन ऐप को IE 7 और सफारी 3 में काम करना था, इसलिए यह एक कारक हो सकता है।

यहाँ एक उदाहरण है कि कैसे पूर्ण राज्य प्राप्त किया जाए:

function MyIframeReadyStateChanged()
{
    if(document.getElementById('myIframe').readyState == 'complete')
    {
        // Do your complete stuff here.
    }
}

6

मैं वेटिंग स्पिनर डिव को छुपाना चाहता था जब आई फ्रेम सामग्री आईई पर पूरी तरह से लोड हो जाती है, मैंने स्टैकओवरफ्लो.कॉम में उल्लिखित हर समाधान का शाब्दिक प्रयास किया, लेकिन जैसा मैं चाहता था, वैसा कुछ भी नहीं हुआ।

तब मुझे अंदाजा था, कि जब आई फ्रेम सामग्री पूरी तरह से भरी हुई है, तो $ (विंडो) लोड घटना को निकाल दिया जा सकता है। और ठीक वैसा ही हुआ। इसलिए, मैंने यह छोटी स्क्रिप्ट लिखी, और जादू की तरह काम किया:

     $(window).load(function () {
     //alert("Done window ready ");
     var lblWait = document.getElementById("lblWait");
     if (lblWait != null ) {
         lblWait.style.visibility = "false";
         document.getElementById("divWait").style.display = "none";
     }
 });

उम्मीद है की यह मदद करेगा।


यह एक सरल उपाय है और यदि आप चाहते हैं कि आपकी जावास्क्रिप्ट को पूरा पृष्ठ लोड होने के बाद निष्पादित किया जाए तो यह ठीक काम करता है। इसका मतलब है कि पहले आप पूरी तरह से लोड किए गए पृष्ठ को देखते हैं, बिना js इफ़ेक्ट के, और हो सकता है कि एक या दो (लोड के आधार पर) के बाद जो कुछ भी जावास्क्रिप्ट द्वारा बनाया जाता है तब होगा। मैंने व्यक्तिगत रूप से अपने आइफ्रेम का आकार बदलने की कोशिश की, और यह काम करता है यदि आप एक पृष्ठ पर क्लिक करने के बाद पहले तीन सेकंड के लिए स्क्रीन पर ध्यान नहीं देते हैं, लेकिन यह कोड के अनुसार पैचवर्क के रूप में दिखाई देता है।
एम्परर्सैंड्स

1
आपकी टिप्पणी के लिए धन्यवाद, इस समाधान ने मेरे मामले में बहुत अच्छा काम किया, क्योंकि मैं चाहता था कि पेज लोड होने के बाद iframe को लोड किया जाए।
नाडा एन। हंतौली

2

मुझे भी आप जैसी ही समस्या थी। मैंने क्या किया कि मैं jQuery नामक कुछ का उपयोग करता हूं। फिर आप जावास्क्रिप्ट कोड में क्या करते हैं:

$(function(){ //this is regular jQuery code. It waits for the dom to load fully the first time you open the page.

    $("#myIframeId").load(function(){
       callback($("#myIframeId").html());
       $("#myIframeId").remove();

    });

});

ऐसा लगता है जैसे आपने html को इससे पहले कि आप हड़प लेते हैं, आपको iFrame हटा दिया। अब, मुझे इसके साथ एक समस्या दिखाई देती है: पी

उम्मीद है की यह मदद करेगा :)।


1

मेरी परियोजनाओं में मेरा समान कोड है जो ठीक काम करता है। अपने फ़ंक्शन के लिए मेरे कोड को अपनाना, एक समाधान निम्नलिखित हो सकता है:

function xssRequest(url, callback)
{
    var iFrameObj = document.createElement('IFRAME');
    iFrameObj.id = 'myUniqueID';
    document.body.appendChild(iFrameObj);       
    iFrameObj.src = url;                        

    $(iFrameObj).load(function() 
    {
        callback(window['myUniqueID'].document.body.innerHTML);
        document.body.removeChild(iFrameObj);
    });
}

हो सकता है कि आपके पास एक खाली इनर HTML हो क्योंकि (एक या दोनों कारण): 1. आपको इसका उपयोग शरीर के तत्व के खिलाफ करना चाहिए। आपने अपने पेज DOM से iframe हटा दिया है


1

मुझे लगता है कि लोड घटना सही है। क्या सही नहीं है जिस तरह से आप iframe सामग्री डोम से सामग्री को पुनः प्राप्त करने के लिए उपयोग करते हैं।

क्या आप की जरूरत है पृष्ठ के HTML iframe में लोड iframe वस्तु के HTML नहीं है।

आपको जो करना है वह सामग्री दस्तावेज़ के साथ करना है iFrameObj.contentDocument। यदि यह वर्तमान पृष्ठ के समान डोमेन पर है, तो यह iframe के अंदर लोड किए गए पृष्ठ के डोम को लौटाता है।

मैं iframe हटाने से पहले सामग्री को फिर से लिखूंगा।

मैंने फ़ायरफ़ॉक्स और ओपेरा में परीक्षण किया है।

तब मुझे लगता है कि आप अपने डेटा को फिर से प्राप्त कर सकते हैं $(childDom).html()या के साथ$(childDom).find('some selector') ...


0

मुझे अतीत में ठीक वैसी ही समस्या हुई है और इसे ठीक करने का एकमात्र तरीका मुझे iframe पेज में कॉलबैक जोड़ना था। बेशक, केवल तभी काम करता है जब आपके पास iframe सामग्री पर नियंत्रण होता है।


22
मैंने आपको वोट नहीं दिया, लेकिन मुझे लगता है कि आपने वोट दिया क्योंकि आपने सुझाव दिया था कि उसने जो कहा वह वह नहीं कर सकता - उसने विशेष रूप से कहा, "IFRAME में सामग्री पर मेरा कोई नियंत्रण नहीं है, इसलिए मैं कर सकता हूं ' t वहां से कॉलबैक फायर करें। "
डेव हेन्स

-1

onloadAttrbute का उपयोग करने से आपकी समस्या दूर हो जाएगी।

यहाँ एक उदाहरण है।

function a() {
alert("Your iframe has been loaded");
}
<iframe src="https://stackoverflow.com" onload="a()"></iframe>

क्या ये वही है जो तुम चाहते हो?

अधिक जानकारी के लिए यहां क्लिक करें

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.