আইফ্রেম এসআরসি পরিবর্তন ইভেন্ট সনাক্তকরণ?


180

ধরে নিলাম আইফ্রেমে লিখিত সামগ্রীর উপর আমার কোনও নিয়ন্ত্রণ নেই, প্যারেন্ট পৃষ্ঠার মাধ্যমে আমি এতে কোনও এসআরসি পরিবর্তন সনাক্ত করতে পারি এমন কোনও উপায় আছে কি? কিছুটা ওভারলোড হয়তো?

আমার শেষ অবলম্বনটি হল 1 সেকেন্ডের ব্যবধান পরীক্ষা করা যদি iframe src আগের মতো হয় তবে এই হ্যাকি সমাধানটি চুষতে পারে।

আমি jQuery লাইব্রেরি ব্যবহার করে যদি এটি সাহায্য করে।


3
srcআইফ্রেমে কোনও লিঙ্ক ক্লিক করলে সম্পত্তি পরিবর্তন হবে ? আমি সে সম্পর্কে নিশ্চিত নই - যদি আমার অনুমান করতে হয়, যদি "না" বলতাম। সেখানে হয় (অন্তত আমি যতদূর জানি এ ফায়ারফক্স মধ্যে) মনিটর বৈশিষ্ট্য উপায়ে কিন্তু আমি নিশ্চিত কিনা এটা এই ক্ষেত্রে কোনো কাজে আসবে না।
পেক্কা

আমি srcএটির মতো কিছু বাস্তবায়নের চেষ্টা করছি এবং নিশ্চিত করতে পারি যে ফায়ারফক্স বা সাফারি এর সর্বশেষ সংস্করণে ডিওমের বৈশিষ্ট্যটি পরিবর্তন হয় না । নীচে @ মিচিয়েলের উত্তরটি যতটা ভাল আমি এতক্ষণ পেতে সক্ষম হয়েছি ঠিক তত ভাল।
ক্যালিন কলকশার

উত্তর:


200

আপনি onLoadনিম্নলিখিত উদাহরণটি হিসাবে ইভেন্টটি ব্যবহার করতে চাইতে পারেন :

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

যখনই iframe এর মধ্যে অবস্থান পরিবর্তন হয় সতর্কতাটি পপ-আপ হবে। এটি সমস্ত আধুনিক ব্রাউজারগুলিতে কাজ করে তবে আই 5 5 এবং প্রারম্ভিক অপেরার মতো বেশ কয়েকটি পুরানো ব্রাউজারে এটি কাজ না করে। ( উত্স )

যদি আইফ্রেমে পিতামাতার একই ডোমেনের মধ্যে একটি পৃষ্ঠা দেখানোcontentWindow.location হয় তবে আপনি নিম্নলিখিত উদাহরণের মতো লোকেশনটি অ্যাক্সেস করতে সক্ষম হবেন :

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

13
আপনার অর্থ this.contentWindow.location.href
নিকোলাই

@ ড্যানিয়েল ভ্যাসাল্লো ধরে নিচ্ছেন আপনি যখন সুরক্ষা ইস্যু পরিচালনা করতে চান তখন আপনি এই প্রচারটি গ্রহণ করছেন, কেউ কি কেবলমাত্র অন্লোড ইভেন্টটিকে ওভাররাইড করতে পারবেন এবং তারপরে আইফ্রেমের সামগ্রী পরিবর্তন করবেন?
নোয়াম শাইশ

15
যখন আমি কি this.contentWindow.location.hrefআমি পেতেPermission denied to access property 'href'
Mazatec,

4
this.contentWindow.location.href আপনি ক্রস অরিজিনের অনুরোধটি করছেন এমন কাজ করবে না bcoz work :( সব ব্রাউজার এখন সীমিত।
নবীন

2
সংশোধন: this.contentWindow.locationঅন্যান্য ডোমেনের জন্য উপলব্ধ। এমনকি this.contentWindow.location.hrefঅন্যান্য ডোমেনগুলির জন্য উপলব্ধ তবে কেবল লেখার জন্য। তবে পড়া this.contentWindow.location.hrefএকই ডোমেনে সীমাবদ্ধ।
ওয়াদিম

57

জিকুয়েরি <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
পরিকল্পনা মতো ঠিক কাজ করে না। এটি প্রাথমিক পৃষ্ঠা লোডের উপর সতর্কতা ফায়ার করে। আপনার কোডগুলি এই কোডটির জন্য কী রয়েছে তার উপর নির্ভর করে (আমার জন্য, আমি ফর্ম জমা দেওয়ার পৃষ্ঠায় ডায়ালগটি অ্যানিমেট করছি) এই সমাধানটি কাজ করবে না।
stacigh

@ স্ট্রেইস, এটি সঠিক, ইভেন্টটি প্রতিবার ফ্রেম লোড হওয়ার সাথে সাথে প্রথম পৃষ্ঠার লোডেও প্রথমবারের মতো জ্বলে উঠবে। আপনি যদি না চান যে আপনার কোডটি প্রথমবার ট্রিগার করা হবে তবে আপনাকে অবশ্যই কোনও কোনওরূপে সনাক্ত করতে হবে এটি আপনার প্রথম ফ্রেমের লোড এবং ফিরে।
মিশিয়েল

@ ফুবার, হ্যাঁ এটি ক্রস ডোমেনের কাজ করে, বাস্তবে এটি আমি এর জন্য ব্যবহার করেছি। যখন পৃষ্ঠাটি অন্য কোনও ডোমেনে থাকে তখন আপনি জাভাস্ক্রিপ্ট সহ আইফ্রেমে পৃষ্ঠাটি অ্যাক্সেস করতে পারবেন না।
মিশিগেল

এটি কাজ করে এবং কন্টেন্টটি লোড হওয়ার সময় সনাক্ত করে, যখন এসআরসি পরিবর্তন করা হয় তখন আমার সনাক্ত করার একটি উপায় প্রয়োজন। লোডের আগের মতো কিছু (একটি লোডার সক্রিয় করতে)
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

মূল প্রশ্নের হিসাবে এখানে উত্তর পোস্ট করা হয়েছে এটির একটি সদৃশ হিসাবে এটি বন্ধ ছিল।


যদি আমি ওয়েব উপাদানগুলি ব্যবহার করি এবং আমার কাস্টম উপাদানগুলির একটিতে একটি এসসিআর বৈশিষ্ট্য রয়েছে? আমি মনে করি এটি দুর্ঘটনাক্রমে এটি বাছাই করবে।
লুক

তারপরে আপনি বিকল্পগুলি পরিবর্তন করুন observe। এইটা শুধুমাত্র একটা উদাহরণ.
Xotic750

@ পলরউব জেসফিডাল লিঙ্কটি সরিয়েছেন (অবশ্যই অনুলিপি / পেস্টের ত্রুটি হওয়া উচিত) এবং স্নিপেট হিসাবে কোডটি অন্তর্ভুক্ত করেছেন।
Xotic750

4
তবে আমার ক্ষেত্রে, ফ্রেম.কন্টেন্ট ডকুমেন্ট.উইআরএল পরিবর্তিত হয় (ফ্রেমের অভ্যন্তরীণ লিঙ্কগুলি থেকে) এসসিআর নয়। আমি কি তা দেখতে পারি?
httpste

নিশ্চিত না, আমার মনে হয় এমন একটি প্রশ্ন লিখতে ভাল।
Xotic750

11

দ্রষ্টব্য: স্নিপেটটি কেবল তখনই কাজ করতে পারে যদি iframe একই উত্সের সাথে থাকে।

অন্যান্য উত্তরের loadইভেন্টটির প্রস্তাব দেওয়া হয়েছিল , তবে ইফ্র্রেমে নতুন পৃষ্ঠাটি লোড হওয়ার পরে এটি জ্বলে উঠবে। নতুন পৃষ্ঠাটি লোড হওয়ার পরে নয়, ইউআরএল পরিবর্তনের সাথে সাথেই আপনাকে অবহিত করতে হবে ।

এখানে একটি সরল জাভাস্ক্রিপ্ট সমাধান:

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 অ্যাট্রিবিউট পরিবর্তনের পাশাপাশি আইফ্রেমের মধ্যে থেকেই তৈরি হওয়া কোনও ইউআরএল পরিবর্তনগুলি ।

সমস্ত আধুনিক ব্রাউজারে পরীক্ষিত।

আমি এই কোডটি দিয়ে একটি গিস্টও তৈরি করেছি। আপনি আমার অন্যান্য উত্তরটিও পরীক্ষা করতে পারেন । এটি কীভাবে কাজ করে তা কিছুটা গভীরতার দিকে যায়।


6

Iframe সর্বদা পিতামাতার পৃষ্ঠা রাখে, আপনি কোন পৃষ্ঠায় iframe এ আছেন তা সনাক্ত করতে আপনার এটি ব্যবহার করা উচিত:

এইচটিএমএল কোড:

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

js:

    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প্রথমে নিজস্ব আইফ্রেমে লোড করে পুরানো মানটির সাথে তুলনা করে, তারপরে বাহ্যিক একটি।

সুতরাং মূলত ধারণাটি হ'ল ফাঁকা পৃষ্ঠাটি নিজের জেএস কোড এবং লুকানো ফর্ম সহ স্থানধারক হিসাবে লোড করা। তারপরে প্যারেন্ট জেএস কোড সেই লুকানো ফর্মটি জমা দেবে যেখানে এর #actionপয়েন্টগুলি বাহ্যিক আইফ্রেমে দেখায়। পুনঃনির্দেশ / জমা দেওয়ার পরে, সেই পৃষ্ঠাটিতে এখনও চলছে এমন জেএস কোডটি আপনার document.location.hrefমান পরিবর্তনগুলি ট্র্যাক করতে পারে।

এখানে উদাহরণস্বরূপ জেএস ইফ্রেমে ব্যবহৃত:

;(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);

তারপরে অস্থায়ী ফাঁকা অবতরণ পৃষ্ঠায় আপনাকে এমন ফর্মটি অন্তর্ভুক্ত করতে হবে যা বাহ্যিক পৃষ্ঠায় পুনর্নির্দেশ করবে।


এটি হ্যাক হতে পারে তবে ওভারহেডটি মিউটেশন পর্যবেক্ষকের তুলনায় যথেষ্ট কম। যখন কোনও একক পৃষ্ঠার অ্যাপ্লিকেশন ব্যবহার করা হয় তখন কোনও রেফারেন্স তৈরি না করার বিষয়ে সচেতন হন যা এই হ্যাক থেকে বাম অংশগুলিকে আবর্জনা সংগ্রহ হতে বাধা দেয়।
জেফ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.