jQuery। একটি গতিশীল ifোকানো iframe প্রস্তুত


184

কেউ যখন কোনও ছবিতে ক্লিক করেন তখন আমরা গতিশীলভাবে একটি আইফ্রেমে প্রদর্শন করতে jQuery ঘনবক্স ব্যবহার করছি । এই iframe এ, আমরা একাধিক ছবি প্রদর্শনের জন্য গ্যালারিয়ার একটি জাভাস্ক্রিপ্ট লাইব্রেরি ব্যবহার করছি ।

সমস্যাটি মনে হচ্ছে যে $(document).readyiframe এ খুব তাড়াতাড়ি বরখাস্ত করা হয়েছে এবং iframe সামগ্রীটি এখনও লোড করা হয়নি, সুতরাং গ্যালেরিয়া কোডটি ডিওএম উপাদানগুলিতে সঠিকভাবে প্রয়োগ করা হয়নি। $(document).readyiframe প্রস্তুত কিনা তা সিদ্ধান্ত নিতে iframe পিতামাতার প্রস্তুত অবস্থা ব্যবহার করে বলে মনে হচ্ছে।

যদি আমরা একটি পৃথক ফাংশনে ডকুমেন্ট দ্বারা প্রস্তুত ফাংশনটি বের করি এবং 100 এমএসের সময়সীমা শেষে কল করি। এটি কাজ করে, তবে আমরা ধীর কম্পিউটারের সাথে উত্পাদনের সুযোগ নিতে পারি না।

$(document).ready(function() { setTimeout(ApplyGalleria, 100); });

আমার প্রশ্ন: গতিশীল iframe প্রস্তুত হয় এবং কেবল এটি কোন পিতামাতার নয়, তবে আমাদের কোডটি কার্যকর করতে সক্ষম হওয়ার জন্য আমাদের কোন jQuery ইভেন্টের সাথে আবদ্ধ হওয়া উচিত?


1
এবং আপনি নিশ্চিত করেছেন যে গ্যালরিয়া কাজ করে যখন আপনি কোনও আইফ্রেমের পরিবর্তে সরাসরি লোড করেন, সঠিক?
জেসন কেলে

হ্যাঁ, গ্যালারিয়া পুরোপুরি কাজ করে যখন আমরা এটিকে কোনও সাধারণ পৃষ্ঠায় সরাসরি ব্যবহার করি।
এটিয়েনটি

উত্তর:


291

আমি একটি অনুরূপ প্রশ্নের উত্তর দিয়েছি ( জাভাস্ক্রিপ্ট কলব্যাক দেখুন যখন IFRAME লোডিং শেষ হয়? ) আপনি নিম্নলিখিত কোড সহ iframe লোড ইভেন্টের উপর নিয়ন্ত্রণ পেতে পারেন:

function callIframe(url, callback) {
    $(document.body).append('<IFRAME id="myId" ...>');
    $('iframe#myId').attr('src', url);

    $('iframe#myId').load(function() {
        callback(this);
    });
}

Iframes নিয়ে কাজ করার সময় আমি ডকুমেন্ট প্রস্তুত ইভেন্টের পরিবর্তে লোড ইভেন্টটি ব্যবহার করার পক্ষে যথেষ্ট ভাল পেয়েছি।


17
অ্যাটর্কে ('src') কল করার আগে লোড ইভেন্টটি সেট করা উচিত নয়?
শাই এরলিচম্যান

15
না, কিছু যায় আসে না। পরের ইভেন্টটি সর্বনিম্ন লুপ হওয়া পর্যন্ত লোড ইভেন্টটি চালিত হবে না।
বারুম রোহ

29
লোড ইভেন্টটি ডাউনলোডের জন্য ব্যবহৃত আইফ্রেমগুলির জন্য কাজ করবে না। <iframe src = "my.pdf" />
মাইক স্টারভ

5
লোডের সমস্যা হ'ল সমস্ত চিত্র এবং সাবফ্রেমগুলি লোড হওয়ার পরে তা আগুন ধরিয়ে দেয়। প্রস্তুত ইভেন্টের মতো একটি jQuery আরও দরকারী হবে।
টম


30

JQuery ব্যবহার করে 1.3.2 নিম্নলিখিত আমার জন্য কাজ করেছে:

$('iframe').ready(function() {
  $('body', $('iframe').contents()).html('Hello World!');
});

REVISION :! প্রকৃতপক্ষে উপরের কোডটি কখনও কখনও ফায়ারফক্সে কাজ করে বলে মনে হয়, এটি অপেরার মতো কাজ করে না।

পরিবর্তে আমি আমার উদ্দেশ্যে একটি ভোটদান সমাধান বাস্তবায়ন করেছি। সরলীকৃত এটি দেখতে এটির মতো দেখাচ্ছে:

$(function() {
  function manipIframe() {
    el = $('body', $('iframe').contents());
    if (el.length != 1) {
      setTimeout(manipIframe, 100);
      return;
    }
    el.html('Hello World!');
  }
  manipIframe();
});

এটির নামক iframe পৃষ্ঠাগুলিতে কোডের প্রয়োজন হয় না। সমস্ত কোড প্যারেন্ট ফ্রেম / উইন্ডো থেকে থাকে এবং কার্যকর করে।


সেটটাইমআউট () এ মুভপ্রিভিউ ফুকশন উল্লেখ করা কী?
cam8001

@ ক্যাম 8001: এটি একটি টাইপো ছিল - এটি এখন ঠিক করা হয়েছে।
মার অ্যারলিগসন

আমিও একটি ভোটগ্রহণ সমাধান ব্যবহার করে শেষ করেছি। অন্যান্য সমাধানগুলি কেবলমাত্র আংশিক সাফল্য নিয়ে কাজ করবে বলে মনে হয়েছিল। তবে আমার পক্ষে আমার সাফল্য পাওয়ার আগে জাফাস্ক্রিপ্ট ফাংশনটির অস্তিত্ব পরীক্ষা করার দরকার ছিল কেবলমাত্র iframe এর বিষয়বস্তু না রেখে success যেমন। (typof iframe.contentWindow.myfunc == 'ফাংশন')
জুলিয়ান

2
এই সমাধানটি পুনরাবৃত্ত হয় যা প্রতিটি কলের জন্য মেমরি গ্রহণ করে। যদি iframe কখনই লোড হয় না, তবে স্মৃতি শেষ না হওয়া পর্যন্ত এটি চিরতরে আরও গভীরতর কল করবে। আমি setIntervalপরিবর্তে ভোট দেওয়ার জন্য সুপারিশ করব ।
এমেজিট করুন

15

আইফ্রেমগুলি আমি সাধারণত ব্লক শেষ করার জন্য একটি ছোট স্ক্রিপ্ট রেখে এই সমস্যার সমাধান:

<body>
The content of your IFrame
<script type="text/javascript">
//<![CDATA[
   fireOnReadyEvent();
   parent.IFrameLoaded();
//]]>
</script>
</body>

এটি বেশিরভাগ সময় আমার জন্য কাজ করে। কখনও কখনও সহজ এবং সবচেয়ে সরল সমাধান সবচেয়ে উপযুক্ত।


4
+1 করুন সমাধান আমার জন্য কাজ করে মহান! একটি দুর্দান্ত সংযোজন হ'ল আপনি parentjQuery এর অনুলিপিটি parent.$(document).ready(function(){ parent.IFrameLoaded( ); });পেতে এবং iframe আরম্ভ করতে ব্যবহার করতে পারেন।
ডেভিড মারডোক

9

ডাঃ জোকপু এবং ডেভিড মারডোক ধারণা অনুসরণ করে আমি আরও একটি সম্পূর্ণ সংস্করণ প্রয়োগ করেছি। এটি প্যারেন্ট এবং আইফ্রেমে এবং আইফ্রেমে উভয়ই আপনার নিয়ন্ত্রণে থাকতে jQuery প্রয়োজন

iframe কোড:

var iframe = window.frameElement;

if (iframe){
    iframe.contentDocument = document;//normalization: some browsers don't set the contentDocument, only the contentWindow

    var parent = window.parent;
    $(parent.document).ready(function(){//wait for parent to make sure it has jQuery ready
        var parent$ = parent.jQuery;

        parent$(iframe).trigger("iframeloading");

        $(function(){
            parent$(iframe).trigger("iframeready");
        });

        $(window).load(function(){//kind of unnecessary, but here for completion
            parent$(iframe).trigger("iframeloaded");
        });

        $(window).unload(function(e){//not possible to prevent default
            parent$(iframe).trigger("iframeunloaded");
        });

        $(window).on("beforeunload",function(){
            parent$(iframe).trigger("iframebeforeunload");
        });
    });
}

পিতামাতার পরীক্ষার কোড:

$(function(){
    $("iframe").on("iframeloading iframeready iframeloaded iframebeforeunload iframeunloaded", function(e){
        console.log(e.type);
    });
});

পিতামাতার মধ্যে if (iframe) .ডিডি (ফাংশন ...) ব্যবহার করা যাই হোক না কেন আমার পক্ষে কাজ করবে না। দেখে মনে হয়েছিল কলফ্যাক ফাংশনটি ইফ্রেমে ডোম প্রস্তুত হওয়ার আগেই কার্যকর হয়ে যাচ্ছে। এই পদ্ধতি ব্যবহার করে দুর্দান্ত কাজ!
w--

4

সমস্যার সমাধান খুঁজে পেয়েছি।

আপনি যদি একটি thickbox লিঙ্ক আছে যা একটি আইফ্রেম খুলতে ক্লিক করেন, তখন এটি TB_iframeContent একজন আইডি সহ একটি iframe সন্নিবেশ করুন।

$(document).readyআইফ্রেমে কোডে ইভেন্টের উপর নির্ভর করার পরিবর্তে , আমাকে কেবল প্যারেন্ট ডকুমেন্টে আইফ্রেমের লোড ইভেন্টের সাথে আবদ্ধ করতে হবে:

$('#TB_iframeContent', top.document).load(ApplyGalleria);

এই কোড আইফ্রেম সিরিজ তবে অভিভাবক নথিতে একটি নিয়ন্ত্রণ একটি ইভেন্টে বেঁধে আছে। এটা তোলে Firefox এবং ইন্টারনেট কাজ করে।


9
সমাধান খুঁজে পেয়েছেন? দেখে মনে হচ্ছে পিয়র এটি ইতিমধ্যে পোস্ট করেছে। আপনি আপনার নিজের উপর এটি পাওয়া থাকুক বা না থাকুক, শিষ্টাচার তার উত্তর গ্রহণ করতে, এইভাবে সময় সে তোমাকে উত্তর অতিবাহিত ফলপ্রসূ হতে হবে।
স্কাই স্যান্ডার্সের

পিয়েরের সমাধান এবং এটির মধ্যে পার্থক্য (এবং আমার কোডটিতে আমি কী অনুপস্থিত ছিল) সেই প্রসঙ্গটি top.documentযা আমাকে iframe এর অভ্যন্তরে কোড রাখতে দেয় যখন iframe লোড হয়েছে তখন তা বলতে সক্ষম হবেন। (যদিও loadএই উত্তরটির পরে on("load")
অবহেলা

2

মূলত অন্যরা ইতিমধ্যে যা পোস্ট করেছে তবে আইএমএইচও একটু ক্লিনার:

$('<iframe/>', {
    src: 'https://example.com/',
    load: function() {
        alert("loaded")
    }
}).appendTo('body');

1

এটা চেষ্টা কর,

<iframe id="testframe" src="about:blank" onload="if (testframe.location.href != 'about:blank') testframe_loaded()"></iframe>

তারপরে আপনাকে যা করতে হবে তা হ'ল জাভাস্ক্রিপ্ট ফাংশন টেস্টফ্রেম_লোড () তৈরি করা।


1
লোডের সমস্যা হ'ল সমস্ত চিত্র এবং সাবফ্রেমগুলি লোড হওয়ার পরে তা আগুন ধরিয়ে দেয়। প্রস্তুত ইভেন্টের মতো একটি jQuery আরও দরকারী হবে।
টম

1

আমি ব্রাউজারের ক্যাশে jQuery আজ্যাক্স সহ পিডিএফটি লোড করছি। তারপর আমি ইতিমধ্যে ব্রাউজারের ক্যাশে ডেটা সঙ্গে এমবেডেড উপাদান তৈরি করুন। আমার ধারণা এটি ইফ্রেমেও কাজ করবে।


var url = "http://example.com/my.pdf";
// show spinner
$.mobile.showPageLoadingMsg('b', note, false);
$.ajax({
    url: url,
    cache: true,
    mimeType: 'application/pdf',
    success: function () {
        // display cached data
        $(scroller).append('<embed type="application/pdf" src="' + url + '" />');
        // hide spinner
        $.mobile.hidePageLoadingMsg();
    }
});

আপনি সঠিকভাবে পাশাপাশি আপনার HTTP হেডার সেট করতে হবে।


HttpContext.Response.Expires = 1;
HttpContext.Response.Cache.SetNoServerCaching();
HttpContext.Response.Cache.SetAllowResponseInBrowserHistory(false);
HttpContext.Response.CacheControl = "Private";

1
মনে রাখবেন, এটি মোবাইল ব্রাউজারে যেখানে ক্যাশে পিডিএফ আকার চেয়ে ছোট হতে পারে উপর ভাল কাজ করে না।
পাভেল Savara

1

এটিই আমাদের ক্লায়েন্টের সাথে আমি সঠিক সমস্যাটি পেয়েছিলাম। আমি একটি সামান্য jquery প্লাগইন তৈরি করেছি যা মনে হয় iframe প্রস্তুতি জন্য কাজ করে। এটি আইফ্রেমে প্রকৃতপক্ষে "প্রস্তুত" আছে কিনা তা নিশ্চিত করার জন্য আইফ্রেমে উত্সের সাথে মিলিত অভ্যন্তরীণ দলিল url এর সাথে মিলিত iframe নথি রেডিস্টেট পরীক্ষা করতে পোলিং ব্যবহার করে।

"অনলোড" সহ সমস্যাটি হ'ল আপনার যদি ডিওএম-তে যুক্ত হয়ে আসল আইফ্রেমে অ্যাক্সেসের প্রয়োজন হয় তবে যদি আপনি তা না করেন তবে আপনার যদি আইফ্রেমে লোডটি ক্যাশে করা হয় তবে তা ধরতে চেষ্টা করতে হবে তবে তা আপনি নাও করতে পারেন। আমার যা দরকার তা হ'ল একটি স্ক্রিপ্ট যা যেকোনো সময় বলা যেতে পারে এবং iframe "প্রস্তুত" ছিল কি না তা নির্ধারণ করে।

এখানে প্রশ্ন:

স্থানীয় iframe লোড হয়েছে কিনা তা নির্ধারণের জন্য পবিত্র গ্রেইল

এবং এখানে jsfiddle আমি অবশেষে সামনে এসেছি।

https://jsfiddle.net/q0smjkh5/10/

উপরে আমি ডোম একটি আইফ্রেম সংযোজন করতে লোড থাকলে জন্য অপেক্ষা করছি, তারপর আইফ্রেম পরীক্ষণ jsfiddle সালে ভেতরের দস্তাবেজের প্রস্তুত রাষ্ট্র নেই - যা ক্রস ডোমেইন হওয়া উচিত, কারণ এটি উইকিপিডিয়ার প্রতি ইঙ্গিত করা হয়েছে - কিন্তু Chrome "সম্পূর্ণ" রিপোর্ট বলে মনে হয়। প্লাগ-ইন এর আইরিডি পদ্ধতিটি যখন আইফ্রেমে আসলে প্রস্তুত থাকে তখন ডাকা হয় called কলব্যাক আবার অভ্যন্তরীণ ডকুমেন্টের প্রস্তুত অবস্থা যাচাই করার চেষ্টা করে - এবার ক্রস ডোমেন অনুরোধের রিপোর্ট করা (যা সঠিক) - যাইহোক এটি আমার প্রয়োজনের জন্য কাজ করছে বলে মনে হয় এবং আশা করি এটি অন্যকে সহায়তা করে।

<script>
  (function($, document, undefined) {
    $.fn["iready"] = function(callback) {
      var ifr = this.filter("iframe"),
          arg = arguments,
          src = this,
          clc = null, // collection
          lng = 50,   // length of time to wait between intervals
          ivl = -1,   // interval id
          chk = function(ifr) {
            try {
              var cnt = ifr.contents(),
                  doc = cnt[0],
                  src = ifr.attr("src"),
                  url = doc.URL;
              switch (doc.readyState) {
                case "complete":
                  if (!src || src === "about:blank") {
                    // we don't care about empty iframes
                    ifr.data("ready", "true");
                  } else if (!url || url === "about:blank") {
                    // empty document still needs loaded
                    ifr.data("ready", undefined);
                  } else {
                    // not an empty iframe and not an empty src
                    // should be loaded
                    ifr.data("ready", true);
                  }

                  break;
                case "interactive":
                  ifr.data("ready", "true");
                  break;
                case "loading":
                default:
                  // still loading
                  break;   
              }
            } catch (ignore) {
              // as far as we're concerned the iframe is ready
              // since we won't be able to access it cross domain
              ifr.data("ready", "true");
            }

            return ifr.data("ready") === "true";
          };

      if (ifr.length) {
        ifr.each(function() {
          if (!$(this).data("ready")) {
            // add to collection
            clc = (clc) ? clc.add($(this)) : $(this);
          }
        });
        if (clc) {
          ivl = setInterval(function() {
            var rd = true;
            clc.each(function() {
              if (!$(this).data("ready")) {
                if (!chk($(this))) {
                  rd = false;
                }
              }
            });

            if (rd) {
              clearInterval(ivl);
              clc = null;
              callback.apply(src, arg);
            }
          }, lng);
        } else {
          clc = null;
          callback.apply(src, arg);
        }
      } else {
        clc = null;
        callback.apply(this, arguments);
      }
      return this;
    };
  }(jQuery, document));
</script>

আমার জন্য ভাল কাজ
হাসান তারেক

0

এই উত্তরটি থেকে এই ফাংশনটি হ্যান্ডেল করার সর্বোত্তম উপায় হ'ল $.readyস্পষ্টভাবে iframes এর ব্যর্থ। এটি সমর্থন না করার সিদ্ধান্ত এখানে

loadঘটনা এছাড়াও আগুন না করলে আইফ্রেম ইতিমধ্যে লোড হওয়ার। খুবই হতাশাজনক যে এই 2020 সালে একটি সমস্যা রয়ে!

function onIframeReady($i, successFn, errorFn) {
    try {
        const iCon = $i.first()[0].contentWindow,
        bl = "about:blank",
        compl = "complete";
        const callCallback = () => {
            try {
                const $con = $i.contents();
             if($con.length === 0) { // https://git.io/vV8yU
                throw new Error("iframe inaccessible");
             }


   successFn($con);
     } catch(e) { // accessing contents failed
        errorFn();
     }
  };
  const observeOnload = () => {
    $i.on("load.jqueryMark", () => {
        try {
            const src = $i.attr("src").trim(),
            href = iCon.location.href;
            if(href !== bl || src === bl || src === "") {
                $i.off("load.jqueryMark");
                callCallback();
            }
        } catch(e) {
            errorFn();
        }
    });
  };
  if(iCon.document.readyState === compl) {
    const src = $i.attr("src").trim(),
    href = iCon.location.href;
    if(href === bl && src !== bl && src !== "") {
        observeOnload();
    } else {
        callCallback();
    }
  } else {
    observeOnload();
  }
} catch(e) {
    errorFn();
}

}

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.