iFrame src परिवर्तन इवेंट डिटेक्शन?


181

मान लें कि आईफ्रेम में सामग्री पर मेरा कोई नियंत्रण नहीं है, तो क्या कोई तरीका है जिससे मैं मूल पृष्ठ के माध्यम से इसमें परिवर्तन का पता लगा सकूं? हो सकता है कि किसी तरह का भार हो?

मेरा आखिरी उपाय है कि अगर सेकंडरी आर्क पहले जैसा ही है तो 1 सेकंड का इंटरवल टेस्ट करना है, लेकिन ऐसा करने से हैकी का समाधान बेकार हो जाएगा।

अगर यह मदद करता है मैं jQuery पुस्तकालय का उपयोग कर रहा हूँ।


3
क्या srciframe में एक लिंक पर क्लिक करने पर संपत्ति बदल जाएगी ? मुझे उस पर यकीन नहीं है - अगर मुझे अनुमान लगाना था, अगर "नहीं" कहेंगे। वहाँ रहे हैं (कम से कम AFAIK पर फ़ायरफ़ॉक्स में) पर नजर रखने के गुण के तरीके लेकिन मुझे यकीन है कि क्या यह इस मामले में किसी भी फायदा नहीं होगा नहीं कर रहा हूँ।
पेका

मैं कुछ इस तरह से लागू करने की कोशिश कर रहा हूं, और यह पुष्टि कर सकता हूं कि srcडोम में विशेषता फायरफॉक्स या सफारी के नवीनतम संस्करणों में नहीं बदलती है। @ मिचेल का जवाब उतना ही अच्छा है जितना मैं अब तक पा सका हूं।
केलिन कॉलक्लासुर

जवाबों:


201

आप onLoadनिम्न उदाहरण में घटना का उपयोग करना चाह सकते हैं :

<iframe src="http://www.google.com/" onLoad="alert('Test');"></iframe>

जब भी iframe में स्थान बदलता है, तो अलर्ट पॉप-अप हो जाएगा। यह सभी आधुनिक ब्राउज़रों में काम करता है, लेकिन IE5 और शुरुआती ओपेरा जैसे कुछ बहुत पुराने ब्राउज़रों में काम नहीं कर सकता है। ( स्रोत )

यदि iframe माता-पिता के समान डोमेन के भीतर एक पृष्ठ दिखा रहा है , तो आप contentWindow.locationनिम्न उदाहरण के साथ , स्थान का उपयोग करने में सक्षम होंगे :

<iframe src="/test.html" onLoad="alert(this.contentWindow.location);"></iframe>

13
आप इसका मतलब है। कॉन्टेंटडब्लू। लोकेशन.हर्फ
निकोलाई

@ डैनियल वेसलो मान लेते हैं कि जब आप सुरक्षा के मुद्दे को संभालना चाहते हैं, तो यह किसी को भी नहीं लेना चाहिए।
नोआम शाश

15
जब मुझे this.contentWindow.location.hrefमिलता हैPermission denied to access property 'href'
Mazatec

4
आप एक क्रॉस ऑरिजिनल रिक्वेस्ट कर रहे हैं। :( सभी ब्राउज़र अब इसे प्रतिबंधित करते हैं।
नवीन

2
सुधार: this.contentWindow.locationअन्य डोमेन के लिए उपलब्ध है। यहां तक ​​कि this.contentWindow.location.hrefअन्य डोमेन के लिए भी उपलब्ध है, लेकिन केवल लेखन के लिए। हालाँकि पढ़ना this.contentWindow.location.hrefउसी डोमेन तक सीमित है।
वादीम

57

उत्तर JQuery <3 पर आधारित है

$('#iframeid').load(function(){
    alert('frame has (re)loaded');
});

जैसा कि सुब्रह्म ने उल्लेख किया है, जैसे कि JQuery 3.0 से इसे बदलने की आवश्यकता है:

$('#iframe').on('load', function() {
    alert('frame has (re)loaded ');
});

https://jquery.com/upgrade-guide/3.0/#breaking-change-load-unload-and-error-removed


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

@stracigh, यह सही है, घटना हर बार फ्रेम लोड होने पर फायर करेगी, इसलिए शुरुआती पेज लोड पर भी पहली बार। यदि आप नहीं चाहते कि आपका कोड पहली बार ट्रिगर हो तो आपको किसी तरह यह पता लगाना चाहिए कि यह आपका पहला फ्रेम लोड है और वापस लौटना है।
मिकिएल

@FooBar, हाँ यह क्रॉस डोमेन का काम करता है, वास्तव में यही वह है जिसके लिए मैंने इसका इस्तेमाल किया है। लेकिन आप iFrame में जावास्क्रिप्ट के साथ उस पृष्ठ को नहीं जोड़ सकते जब वह पृष्ठ किसी अन्य डोमेन पर हो।
मिकिएल

यह काम करता है और पता लगाता है कि सामग्री लोड होने पर, मुझे यह पता लगाने के लिए एक तरीका चाहिए जब बदलने में src। इससे पहले की तरह कुछ (लोडर सक्रिय करने के लिए)
Andrea_86

जैसा कि @ बाधा द्वारा संकेत दिया गया है, यह मूल पृष्ठ लोड पर एक बार घटना को आग देगा। यदि आप उस फ़ंक्शन के बाहर एक काउंटर घोषित करते हैं और इसे अंदर पढ़ते हैं, तो आप उसके बाद के परिवर्तनों का पता लगा सकते हैं। आप ऑनलोड हैंडलर प्लस के अंदर इन्क्रीमेंट काउंटर लेंगे if (counter > 1) { // do something on iframe actual change }(मान लें कि काउंटर शुरू में 0 पर सेट किया गया था)
एलेक्स

38

यदि आपके पास पृष्ठ पर कोई नियंत्रण नहीं है और किसी प्रकार के परिवर्तन को देखने की इच्छा है, तो आधुनिक पद्धति का उपयोग करना है MutationObserver

इसके उपयोग का एक उदाहरण, srcएक को बदलने की विशेषता के लिए देख रहा हैiframe

new MutationObserver(function(mutations) {
  mutations.some(function(mutation) {
    if (mutation.type === 'attributes' && mutation.attributeName === 'src') {
      console.log(mutation);
      console.log('Old src: ', mutation.oldValue);
      console.log('New src: ', mutation.target.src);
      return true;
    }

    return false;
  });
}).observe(document.body, {
  attributes: true,
  attributeFilter: ['src'],
  attributeOldValue: true,
  characterData: false,
  characterDataOldValue: false,
  childList: false,
  subtree: true
});

setTimeout(function() {
  document.getElementsByTagName('iframe')[0].src = 'http://jsfiddle.net/';
}, 3000);
<iframe src="http://www.google.com"></iframe>

3 सेकंड के बाद आउटपुट

MutationRecord {oldValue: "http://www.google.com", attributeNamespace: null, attributeName: "src", nextSibling: null, previousSibling: null…}
Old src:  http://www.google.com
New src:  http://jsfiddle.net/ 

पर jsFiddle

मूल प्रश्न के रूप में यहां पोस्ट किया गया उत्तर इस के डुप्लिकेट के रूप में बंद था।


यदि मैं वेब कंपोनेंट्स का उपयोग कर रहा हूं और मेरे कस्टम घटकों में से एक में src विशेषता है? मुझे लगता है कि यह गलती से इसे उठा लेगा।
ल्यूक

फिर आप विकल्पों को बदलते हैं observe। यह सिर्फ एक उदाहरण है।
Xotic750

@PaRRoub ने jsfiddle लिंक को हटा दिया (कॉपी / पेस्ट एरर होना चाहिए) और कोड को स्निपेट के रूप में शामिल किया।
Xotic750

4
लेकिन मेरे मामले में, फ्रेम। कॉंटेंटडेंक्मेंट.यूआरएल परिवर्तन (फ्रेम के अंदर लिंक से) src नहीं। क्या मैं उसे देख सकता हूँ?
httpete

मुझे यकीन नहीं है, सबसे अच्छा मुझे लगता है कि एक प्रश्न लिखने के लिए।
Xotic750

11

नोट: स्निपेट केवल तभी काम करेगा जब आइफ्रेम एक ही मूल के साथ हो।

अन्य जवाबों ने इस loadघटना का प्रस्ताव रखा , लेकिन इफ्रेम में नया पेज लोड होने के बाद यह आग लग गईURL बदलने के तुरंत बाद आपको सूचित करना होगा , न कि नया पेज लोड होने के बाद।

यहाँ एक सादे जावास्क्रिप्ट समाधान है:

function iframeURLChange(iframe, callback) {
    var unloadHandler = function () {
        // Timeout needed because the URL changes immediately after
        // the `unload` event is dispatched.
        setTimeout(function () {
            callback(iframe.contentWindow.location.href);
        }, 0);
    };

    function attachUnload() {
        // Remove the unloadHandler in case it was already attached.
        // Otherwise, the change will be dispatched twice.
        iframe.contentWindow.removeEventListener("unload", unloadHandler);
        iframe.contentWindow.addEventListener("unload", unloadHandler);
    }

    iframe.addEventListener("load", attachUnload);
    attachUnload();
}

iframeURLChange(document.getElementById("mainframe"), function (newURL) {
    console.log("URL changed:", newURL);
});
<iframe id="mainframe" src=""></iframe>

यह srcविशेषता परिवर्तनों को सफलतापूर्वक ट्रैक करेगा , साथ ही साथ iframe के भीतर से किए गए कोई भी URL परिवर्तन।

सभी आधुनिक ब्राउज़रों में परीक्षण किया गया।

मैंने इस कोड के साथ एक जिस्ट बनाया । आप मेरे दूसरे उत्तर को भी देख सकते हैं। यह कैसे काम करता है, इस बारे में गहराई से जाना जाता है।


6

Iframe हमेशा पेरेंट पेज रखता है, आपको इसका उपयोग यह पता लगाने के लिए करना चाहिए कि आप iframe में किस पेज पर हैं:

HTML कोड:

<iframe id="iframe" frameborder="0" scrolling="no" onload="resizeIframe(this)" width="100%" src="www.google.com"></iframe>

जे एस:

    function resizeIframe(obj) {
        alert(obj.contentWindow.location.pathname);
    }

2

Jquery के संस्करण 3.0 के बाद से आपको एक त्रुटि मिल सकती है

TypeError: url.indexOf कोई फ़ंक्शन नहीं है

जिसे आसानी से करके ठीक किया जा सकता है

$('#iframe').on('load', function() {
    alert('frame has (re)loaded ');
});

1

यहाँ वह विधि है जो वाणिज्य ऋषिपय में और वाणिज्य पिप्पु द्रुपाल मॉड्यूल में उपयोग की जाती है जो मूल रूप document.location.hrefसे पहले अपने स्वयं के iframe को लोड करके पुराने मूल्य के साथ तुलना करता है, फिर बाहरी।

तो मूल रूप से विचार अपने स्वयं के जेएस कोड और छिपे हुए फॉर्म के साथ रिक्त पृष्ठ को एक प्लेसहोल्डर के रूप में लोड करना है। तब माता-पिता जेएस कोड उस छिपे हुए फॉर्म को सबमिट करेंगे जहां इसके #actionबाहरी iframe के बिंदु हैं। एक बार रीडायरेक्ट / सबमिट होने के बाद, JS कोड जो उस पेज पर अभी भी चल रहा है, आपके document.location.hrefमूल्य परिवर्तनों को ट्रैक कर सकता है ।

यहाँ उदाहरण है जेएस iframe में इस्तेमाल किया:

;(function($) {
  Drupal.behaviors.commercePayPointIFrame = {
    attach: function (context, settings) {
      if (top.location != location) {
        $('html').hide();
        top.location.href = document.location.href;
      }
    }
  }
})(jQuery);

और यहाँ जेएस मूल पृष्ठ में प्रयोग किया जाता है:

;(function($) {
  /**
   * Automatically submit the hidden form that points to the iframe.
   */
  Drupal.behaviors.commercePayPoint = {
    attach: function (context, settings) {
      $('div.payment-redirect-form form', context).submit();
      $('div.payment-redirect-form #edit-submit', context).hide();
      $('div.payment-redirect-form .checkout-help', context).hide();
    }
  }
})(jQuery);

फिर अस्थायी रिक्त लैंडिंग पृष्ठ में आपको वह फ़ॉर्म शामिल करना होगा जो बाहरी पृष्ठ पर रीडायरेक्ट करेगा।


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