जब तक jquery लोड न हो, तब तक स्क्रिप्ट निष्पादन को कैसे प्रतीक्षा करें


106

मुझे एक समस्या आ रही है जहाँ पृष्ठ इतनी तेज़ी से लोड हो रहा है, कि jquery ने बाद की स्क्रिप्ट द्वारा कॉल किए जाने से पहले लोडिंग समाप्त नहीं की है। क्या वहाँ एक रास्ता है जो कि अस्तित्व के लिए जाँच करता है और अगर यह मौजूद नहीं है, तो एक पल के लिए रुकें और फिर दोबारा कोशिश करें।


नीचे दिए गए उत्तर / टिप्पणियों के जवाब में, मैं कुछ मार्कअप पोस्ट कर रहा हूं।

स्थिति ... asp.net मास्टरपेज और चाइल्डपेज।

मास्टरपेज में, मेरे पास jquery का संदर्भ है। फिर सामग्री पृष्ठ में, मेरे पास पृष्ठ-विशिष्ट स्क्रिप्ट का संदर्भ है। जब पृष्ठ विशिष्ट स्क्रिप्ट लोड किया जा रहा है, तो यह शिकायत करता है कि "$ अपरिभाषित है"।

मैं मार्कअप में कई बिंदुओं पर अलर्ट डालता हूं ताकि उस क्रम को देखा जा सके जिसमें चीजें फायरिंग कर रही थीं, और पुष्टि की कि यह इस क्रम में फायर करता है:

  1. मास्टर पेज हैडर।
  2. चाइल्ड पेज कंटेंट ब्लॉक 1 (मास्टरपेज के सिर के अंदर स्थित है, लेकिन मास्टरपेज स्क्रिप्ट के बाद कहा जाता है)।
  3. बाल पृष्ठ सामग्री ब्लॉक 2।

यहाँ मुख्य पृष्ठ के शीर्ष पर मार्कअप है:

<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Site.master.cs" Inherits="SiteMaster" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title>Reporting Portal</title>
    <link href="~/Styles/site.css" rel="stylesheet" type="text/css" />
    <link href="~/Styles/red/red.css" rel="stylesheet" type="text/css" />
    <script type="text/Scripts" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script> 
    <script type="text/Scripts" language="javascript" src="../Scripts/jquery.dropdownPlain.js"></script>
    <script type="text/Scripts" language="javascript" src="../Scripts/facebox.js"></script>
    <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
    <asp:ContentPlaceHolder ID="head" runat="server">
    </asp:ContentPlaceHolder>
</head>

फिर मुख्यपृष्ठ के मुख्य भाग में, एक अतिरिक्त ContentPlaceHolder है:

 <asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server">
                </asp:ContentPlaceHolder>

बाल पृष्ठ में, ऐसा दिखता है:

<%@ Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Dashboard.aspx.cs" Inherits="Data.Dashboard" %>
<%@ Register src="../userControls/ucDropdownMenu.ascx" tagname="ucDropdownMenu" tagprefix="uc1" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
    <link rel="stylesheet" type="text/css" href="../Styles/paserMap.css" />
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
***CONTENT HERE***
    <script src="../Scripts/Dashboard.js" type="text/javascript"></script>
</asp:Content>

यहाँ "../Script/Dashboard.js" फ़ाइल की सामग्री है:

    $(document).ready(function () {

    $('.tgl:first').show(); // Show the first div

    //Description: East panel parent tab navigation
    $('.tabNav label').click(function () {
        $('.tabNav li').removeClass('active')
        $(this).parent().addClass('active');

        var index = $(this).parent('li').index();
        var divToggle = $('.ui-layout-content').children('div.tgl');

        //hide all subToggle divs
        divToggle.hide();
        divToggle.eq(index).show();
    });

});

4
क्या आप उपयोग कर रहे हैं $(document).ready(function(){...});?
13

यदि आप सरल <script src="...">टैग के साथ स्क्रिप्ट लोड कर रहे हैं , तो ऐसा नहीं हो सकता। क्या आप आवश्यकता या LABJs जैसी किसी चीज़ का उपयोग कर रहे हैं?
नुकीले

क्या आप बाद में स्क्रिप्ट चला रहे हैं $(document).ready()या $(window).load()? क्या हम एक उदाहरण देख सकते हैं?
जॉन हार्टसॉक सेप

1
@AmandaMyer अब, दस्तावेज़ का उपयोग करने के बारे में सभी सुझावों को अनदेखा करें, क्योंकि आप पहले से ही ऐसा कर रहे हैं, लेकिन मुझे यकीन है कि यह mimetype है जो उन्हें तुल्यकालिक रूप से लोड नहीं करने का कारण बना रहा है
Sander

2
बदलने का प्रयास करें type="text/Scripts"करने के लिए type="text/javascript", या सभी को एक साथ यह अब कोई आवश्यकता नहीं है यह से छुटकारा पाने के, यह भी से छुटकारा पाने के language="javascript। साथ ही चीजों को आजमाना शुरू कर सकते हैं।
जैक

जवाबों:


11

संपादित करें

क्या आप अपने स्क्रिप्ट टैग के लिए सही प्रकार का प्रयास कर सकते हैं? मैं आपको उपयोग करते हुए देखता हूं text/Scripts, जो जावास्क्रिप्ट के लिए सही mimetype नहीं है।

इसे इस्तेमाल करो:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script> 
<script type="text/javascript" src="../Scripts/jquery.dropdownPlain.js"></script>
<script type="text/javascript" src="../Scripts/facebox.js"></script>

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

या आप आवश्यकता पर एक नज़र डाल सकते हैं। जेएस जो आपके जावास्क्रिप्ट कोड के लिए लोडर है।

आपके प्रोजेक्ट के आधार पर, यह हालांकि थोड़ा ओवरकिल हो सकता है


205

पार्टी के लिए देर हो चुकी है, और Briguy37 के सवाल के समान है, लेकिन भविष्य के संदर्भ के लिए मैं निम्नलिखित विधि का उपयोग करता हूं और उन कार्यों में पास करता हूं जिन्हें मैं jQuery लोड होने तक स्थगित करना चाहता हूं:

function defer(method) {
    if (window.jQuery) {
        method();
    } else {
        setTimeout(function() { defer(method) }, 50);
    }
}

जब तक window.jQueryयह बाहर निकलता है और कॉल करता है, तब तक यह हर 50ms पर आवर्ती तरीके से कॉल करेगाmethod()

एक अनाम फ़ंक्शन के साथ एक उदाहरण:

defer(function () {
    alert("jQuery is now loaded");
});

2
इसने मेरे लिए काम नहीं किया। विधि के अंदर, $ परिभाषित नहीं किया गया था ... निश्चित नहीं है कि अभी तक क्यों।
एरोन लाइफशिन

यह उस साइट में काम करने वाले कुछ कस्टम कोड प्राप्त करने के लिए एक अच्छा समाधान था, जिसे एडोब सरस्वती में किसी और द्वारा डिजाइन किया गया था।
Buggabill

@ गिडिम यह नहीं होगा, क्योंकि यह टाइमर है और लूप नहीं है। लेकिन यह तब तक चलता रहेगा जब तक पेज पर यूजर रहेगा।
माइक्रोस

लिपियों के लोडिंग ऑर्डर की जांच करना बेहतर होगा। मैंने पाया कि अगर scriptjQuery को लोड करने वाले टैग में एक deferविशेषता थी, तो यह स्क्रिप्ट के कोड-परिभाषित आदेश के बावजूद, बाद तक लोड नहीं होने से समस्या का कारण होगा।
ADTC

19

आप स्क्रिप्ट को वास्तव में अंत में लोड करने के लिए डिफर विशेषता का उपयोग कर सकते हैं।

<script type='text/javascript' src='myscript.js' defer='defer'></script>

लेकिन सामान्य रूप से आपकी स्क्रिप्ट को सही क्रम में लोड करने की कोशिश करनी चाहिए, इसलिए अपनी स्क्रिप्ट से पहले jquery को शामिल करना सुनिश्चित करें

यदि आपका कोड पृष्ठ में है और एक अलग js फ़ाइल में नहीं है, तो आपको दस्तावेज़ तैयार होने के बाद ही अपनी स्क्रिप्ट को निष्पादित करना होगा और अपने कोड को इस तरह से एनकैप्सुलेट करना होगा:

$(function(){
//here goes your code
});

यह ठीक है जब तक आपके पास एक एकल निर्भरता है
गिलौम मास

17

फिर भी ऐसा करने का एक और तरीका है, हालांकि डार्बियो की डिफर विधि अधिक लचीली है।

(function() {
  var nTimer = setInterval(function() {
    if (window.jQuery) {
      // Do something with jQuery
      clearInterval(nTimer);
    }
  }, 100);
})();

16

सबसे आसान और सुरक्षित तरीका कुछ इस तरह का उपयोग करना है:

var waitForJQuery = setInterval(function () {
    if (typeof $ != 'undefined') {

        // place your code here.

        clearInterval(waitForJQuery);
    }
}, 10);

2
प्रतिभाशाली समाधान। धन्यवाद
डिएगो फोर्ट्स

13

आप ऑनलोड ईवेंट की कोशिश कर सकते हैं। यह तब बढ़ा जब सभी लिपियों को लोड किया गया:

window.onload = function () {
   //jquery ready for use here
}

लेकिन ध्यान रखें, कि आप अन्य स्क्रिप्ट को ओवरराइड कर सकते हैं जहाँ window.onload का उपयोग कर रहे हैं।


यह काम करता है, लेकिन आप शायद अस्थिर सामग्री का एक फ्लैश देखेंगे यदि आपका jquery पृष्ठ की उपस्थिति को बदल देता है
मैथ्यू लॉक

1
अन्य स्क्रिप्ट को ओवरराइड करने से बचने के लिए आप एक ईवेंट श्रोता जोड़ सकते हैं: stackoverflow.com/a/15564394/32453 FWIW '
rogerdpack

@rogerdpack सहमत है, यह बेहतर समाधान है।
निग्रिमिस्ट

10

मैंने पाया है कि सुझाए गए समाधान अतुल्यकालिक कोड को ध्यान में रखते हुए ही काम करते हैं। यहाँ वह संस्करण है जो किसी भी स्थिति में काम करेगा:

document.addEventListener('DOMContentLoaded', function load() {
    if (!window.jQuery) return setTimeout(load, 50);
    //your synchronous or asynchronous jQuery-related code
}, false);

धन्यवाद, लोड पर एक बार जाँच करना और केवल 50 सेकंड में कमबैक करना शुरू करना, सिर्फ सेट वोट के साथ इसे लूप देने की तुलना में बेहतर है, जैसे कि टॉप वोट किया गया उत्तर। शीर्ष उत्तर के 25ms के औसत मामले के बजाय आपके पास सबसे अच्छा मामले में 0ms देरी है।
ल्यूक

अच्छा और सुरुचिपूर्ण - मुझे पसंद है कि आप loadफ़ंक्शन कैसे पास करते हैं, लेकिन फिर इसमें पुन: उपयोग भी करते हैं setTimeout
नेमेसेरियल

6

यह एक सामान्य मुद्दा है, कल्पना कीजिए कि आप एक शांत PHP टेम्प्लेटिंग इंजन का उपयोग करते हैं, इसलिए आपके पास अपना आधार लेआउट है:

HEADER
BODY ==> dynamic CONTENT/PAGE
FOOTER

और हां, आपने कहीं पढ़ा है कि पेज के निचले हिस्से पर जावास्क्रिप्ट लोड करना बेहतर है, इसलिए आपकी डायनामिक सामग्री को पता नहीं है कि कौन jQuery है (या $)।

इसके अलावा, आपने कहीं पढ़ा है यह छोटे जावास्क्रिप्ट को इनलाइन करना अच्छा है, इसलिए कल्पना करें कि आपको एक पृष्ठ में jQuery की आवश्यकता है, baboom, $ परिभाषित नहीं है (.. अभी तक ^ ^)।

मुझे फेसबुक द्वारा दिए गए समाधान से प्यार है

window.fbAsyncInit = function() { alert('FB is ready !'); }

तो एक आलसी प्रोग्रामर के रूप में (मुझे एक अच्छा प्रोग्रामर ^ ^ कहना चाहिए), आप एक समकक्ष (अपने पेज के भीतर) का उपयोग कर सकते हैं:

window.jqReady = function() {}

और jQuery के शामिल होने के बाद, अपने लेआउट के निचले भाग में जोड़ें

if (window.hasOwnProperty('jqReady')) $(function() {window.jqReady();});

धन्यवाद! ठीक यही स्थिति मेरे सामने है।
कुम्ज


5

"प्रतीक्षा" के बजाय (जो आमतौर पर उपयोग किया जाता है setTimeout), आप अपने कोड को निष्पादित करने के लिए हुक के रूप में विंडो में jQuery ऑब्जेक्ट को परिभाषित करने का उपयोग भी कर सकते थे जो इस पर निर्भर करता है। यह एक संपत्ति परिभाषा के माध्यम से प्राप्त करने योग्य है, जिसका उपयोग करके परिभाषित किया गया है Object.defineProperty

(function(){
  var _jQuery;
  Object.defineProperty(window, 'jQuery', {
    get: function() { return _jQuery; },
    set: function($) {
      _jQuery = $;

      // put code or call to function that uses jQuery here

    }
  });
})();

यह वास्तव में उपयोगी होगा यदि jQuery वास्तव में एक विंडो प्रॉपर्टी को परिभाषित करता है, लेकिन ऐसा नहीं लगता है?
जिम

यह वास्तव में एक संपत्ति निर्धारित नहीं करता है, लेकिन यह वैश्विक दायरे (यानी ) में चर को window.jQueryपरिभाषित करके एक मूल्य पर सेट होता है । यह कोड में परिभाषित विंडो ऑब्जेक्ट पर गुण सेटर फ़ंक्शन को ट्रिगर करेगा। jQuerywindow
रक्षक एक

इस कोड के निष्पादित होने से पहले jQuery की संपत्ति परिभाषित हो जाने पर यह काम नहीं करता है; यदि इस कोड को लोड करने से पहले आपका स्थगित jquery.js लोड हो जाता है। इसका एक उपाय यह है कि आप पहले के </body>बजाय अपने स्थगित jquery.js को डाल दें</head>
user36388

@user: बस jQuery से पहले कोड को निष्पादित करें (स्थगित या अन्यथा) लोड किया गया है। इससे कोई फर्क नहीं पड़ता कि आप इसे कहां लोड करते हैं, बस इससे पहले कि मेरा कोड टुकड़ा आता है।
रक्षक एक

1
यह बहुत उपयोगी है यदि आप गारंटी दे सकते हैं कि इसका उपयोग करने वाली स्क्रिप्ट आपके दस्तावेज़ में jQuery के शामिल होने से पहले आती हैं। ऊपर से लूपिंग दृष्टिकोण से कोई भी अक्षमता या दौड़-मामला परिदृश्य नहीं है।
RedYetiCo

4

उपयोग:

$(document).ready(function() {
    // put all your jQuery goodness in here.
});

अधिक जानकारी के लिए इसे देखें: http://www.learningjquery.com/2006/09/introducing-document-ready

नोट: यह तब तक काम करना चाहिए जब तक कि आपकी JQuery लाइब्रेरी के लिए स्क्रिप्ट आयात इस कॉल के ऊपर न हो जाए।

अपडेट करें:

यदि किसी कारण से आपका कोड सिंक्रोनाइज़ नहीं हो रहा है (जो मैंने कभी नहीं चलाया है, लेकिन जाहिरा तौर पर टिप्पणी से संभव हो सकता है नीचे नहीं होना चाहिए), तो आप इसे निम्न की तरह कोड कर सकते हैं।

function yourFunctionToRun(){
    //Your JQuery goodness here
}

function runYourFunctionWhenJQueryIsLoaded() {
    if (window.$){
        //possibly some other JQuery checks to make sure that everything is loaded here

        yourFunctionToRun();
    } else {
        setTimeout(runYourFunctionWhenJQueryIsLoaded, 50);
    }
}

runYourFunctionWhenJQueryIsLoaded();

6
इस इंतजार को पूरा करें कि डोम तैयार है, न कि अनछुए जक्वेरी। उसके पास शायद 2 स्क्रिप्ट फाइलें हैं, 1 सीडीएन (गूगल से jquery और स्थानीय रूप से एक प्लगइन) जहां 1 दूसरे से पहले लोड किया गया है .... आपका कोड इसे हल नहीं करता है, अगर प्लगइन jquery की तुलना में तेजी से लोड होता है
सैंडर

2
मैं तुमसे असहमत हूँ @ इस तरह काम करना चाहिए क्योंकि लोडिंग तुल्यकालिक है
14

आप सही हैं, उनके बारे में मेरी धारणा अतुल्यकालिक लोड की जा रही है अगर वे एक अलग डोमेन से आते हैं पूरी तरह से गलत है! इसके लिए मुझे क्षमा करें
Sander

यह एक अपवाद को फेंक देगा यदि jquery उपलब्ध नहीं है, क्योंकि यह कभी भी दूसरे के बयान में नहीं जाता है जो ऐसा लगता है। यह एक कोशिश और पकड़ने या कुछ और होना चाहिए लगता है।
सैम स्टोइलिंगा

@SamStoelinga: धन्यवाद, यह अब तय किया जाना चाहिए।
Briguy37

3

मैं अंतराल की बातों का सुपर शौकीन नहीं हूं। जब मैं वास्तव में jquery, या किसी भी चीज़ को टालना चाहता हूं, तो यह आमतौर पर कुछ इस तरह से होता है।

के साथ शुरू:

<html>
 <head>
  <script>var $d=[];var $=(n)=>{$d.push(n)}</script>
 </head>

फिर:

 <body>
  <div id="thediv"></div>

  <script>
    $(function(){
       $('#thediv').html('thecode');
    });
  </script>

  <script src="http://code.jquery.com/jquery-3.2.1.min.js" type="text/javascript"></script>

फिर अंत में:

  <script>for(var f in $d){$d[f]();}</script>
 </body>
<html>

या कम दिमाग वाला संस्करण:

<script>var def=[];function defer(n){def.push(n)}</script>
<script>
defer(function(){
   $('#thediv').html('thecode');
});
</script>
<script src="http://code.jquery.com/jquery-3.2.1.min.js" type="text/javascript"></script>
<script>for(var f in def){def[f]();}</script>

और async के मामले में आप jquery onload पर धकेल दिए गए कार्यों को निष्पादित कर सकते हैं।

<script async onload="for(var f in def){def[f]();}" 
src="jquery.min.js" type="text/javascript"></script>

वैकल्पिक रूप से:

function loadscript(src, callback){
  var script = document.createElement('script');
  script.src = src
  script.async = true;
  script.onload = callback;
  document.body.appendChild(script);
};
loadscript("jquery.min", function(){for(var f in def){def[f]();}});

2

मुझे नहीं लगता कि यह आपकी समस्या है। स्क्रिप्ट लोडिंग डिफ़ॉल्ट रूप से समकालिक है, इसलिए जब तक आप deferविशेषता का उपयोग नहीं कर रहे हैं या एक और AJAX अनुरोध के माध्यम से jQuery लोड नहीं कर रहे हैं, तो आपकी समस्या संभवतः 404 जैसी कुछ और है। क्या आप अपना मार्कअप दिखा सकते हैं, और हमें बताएं कि क्या आपको कुछ भी संदिग्ध दिखाई दे रहा है फायरबग या वेब इंस्पेक्टर?


2

चलो defer()अधिक से पुन: प्रयोज्य होने के लिए डारियो से विस्तार करें ।

function defer(toWaitFor, method) {
    if (window[toWaitFor]) {
        method();
    } else {
        setTimeout(function () { defer(toWaitFor, method) }, 50);
    }
}

जो तब चलाया जाता है:

function waitFor() {
    defer('jQuery', () => {console.log('jq done')});
    defer('utag', () => {console.log('utag done')});
}

1

इसे देखो:

https://jsfiddle.net/neohunter/ey2pqt5z/

यह एक नकली jQuery ऑब्जेक्ट बनाएगा, जो आपको jquery के ऑनलोड तरीकों का उपयोग करने की अनुमति देता है, और जैसे ही jquery लोड होता है, उन्हें निष्पादित किया जाएगा।

यह सही नहीं है।

// This have to be on <HEAD> preferibly inline
var delayed_jquery = [];
jQuery = function() {
  if (typeof arguments[0] == "function") {
    jQuery(document).ready(arguments[0]);
  } else {
    return {
      ready: function(fn) {
        console.log("registering function");
        delayed_jquery.push(fn);
      }
    }
  }
};
$ = jQuery;
var waitForLoad = function() {
  if (typeof jQuery.fn != "undefined") {
    console.log("jquery loaded!!!");
    for (k in delayed_jquery) {
      delayed_jquery[k]();
    }
  } else {
    console.log("jquery not loaded..");
    window.setTimeout(waitForLoad, 500);
  }
};
window.setTimeout(waitForLoad, 500);
// end



// now lets use jQuery (the fake version)
jQuery(document).ready(function() {
  alert('Jquery now exists!');
});

jQuery(function() {
  alert('Jquery now exists, this is using an alternative call');
})

// And lets load the real jquery after 3 seconds..
window.setTimeout(function() {
  var newscript = document.createElement('script');
  newscript.type = 'text/javascript';
  newscript.async = true;
  newscript.src = 'https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js';
  (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(newscript);
}, 3000);


यह दस्तावेज़ तैयार कार्यों को पंजीकृत करने के लिए कोई परेशानी समाधान नहीं है धन्यवाद
zanedev

0

दृष्टिकोण पर एक स्पर्शरेखा नोट जो लोड का उपयोग करता है setTimeoutया setInterval। उन मामलों में यह संभव है कि जब आपका चेक फिर से चलता है, तो डोम पहले ही लोड हो जाएगा, और ब्राउज़र की DOMContentLoadedघटना को निकाल दिया जाएगा, इसलिए आप इन तरीकों का उपयोग करके मज़बूती से उस घटना का पता नहीं लगा सकते हैं। मैंने पाया है कि jQuery का readyअभी भी काम करता है, हालांकि, आप अपने सामान्य को एम्बेड कर सकते हैं

jQuery(document).ready(function ($) { ... }

अपने setTimeoutया setIntervalसब कुछ के अंदर सामान्य रूप से काम करना चाहिए।

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