130 votes

Comment faire en sorte que l'exécution de script attende que jquery soit chargé ?

J'ai un problème où la page se charge tellement vite que jquery n'a pas fini de se charger avant d'être appelé par un script ultérieur. Existe-t-il un moyen de vérifier l'existence de jquery et, s'il n'existe pas, d'attendre un moment puis de réessayer ?


En réponse aux réponses/commentaires ci-dessous, je mets en ligne une partie du balisage.

La situation... asp.net masterpage et childpage.

Dans la page principale, j'ai une référence à jquery. Ensuite, dans la page de contenu, j'ai une référence au script spécifique à la page. Lorsque le script spécifique à la page est chargé, il se plaint que "$ est indéfini".

J'ai placé des alertes à plusieurs endroits du balisage pour voir dans quel ordre les choses se déclenchaient, et j'ai confirmé qu'elles se déclenchaient dans cet ordre :

  1. En-tête de la page principale.
  2. Le bloc de contenu 1 de la page enfant (situé à l'intérieur du de la page maîtresse, mais après que les scripts de la page maîtresse sont appelés).
  3. Bloc de contenu de la page enfant 2.

Voici le balisage en haut de la page principale :

<%@ 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>

Ensuite, dans le corps de la page principale, il y a un ContentPlaceHolder supplémentaire :

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

Dans la page de l'enfant, cela se présente comme suit :

<%@ 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>

Voici le contenu du fichier "../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();
    });

});

12voto

Sander Points 7078

éditer

Pourriez-vous essayer d'utiliser le type correct pour vos balises script ? Je vois que vous utilisez text/Scripts qui n'est pas le bon mimetype pour le javascript.

Utilisez ceci :

<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>

Fin de l'édition

ou vous pouvez jeter un coup d'œil sur require.js qui est un chargeur pour votre code javascript.

en fonction de votre projet, cela pourrait toutefois être un peu excessif

6voto

Briguy37 Points 4748

Utiliser :

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

Pour plus d'informations, consultez le site suivant : http://www.learningjquery.com/2006/09/introducing-document-ready

Remarque : cela devrait fonctionner tant que l'importation script de votre bibliothèque JQuery se trouve au-dessus de cet appel.

Mise à jour :

Si, pour une raison quelconque, votre code ne se charge pas de manière synchrone (ce qui est le cas de Je n'ai jamais rencontré ce type de problème, mais il semblerait que ce soit possible d'après le commentaire ci-dessous ne devrait pas se produire), vous pourriez le coder comme suit.

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

6voto

Thomas Decaux Points 2613

Il s'agit d'un problème courant. Imaginez que vous utilisiez un moteur de création de modèles en PHP, et que vous disposiez ainsi d'une présentation de base :

HEADER
BODY ==> dynamic CONTENT/PAGE
FOOTER

Et bien sûr, vous avez lu quelque part qu'il est préférable de charger Javascript en bas de page, de sorte que votre contenu dynamique ne sache pas qui est jQuery (ou le $).

De plus, vous avez lu quelque part qu'il est bon d'inline les petits Javascript, donc imaginez que vous ayez besoin de jQuery dans une page, baboom, $ n'est pas défini ( pour l'instant ^^).

J'aime la solution proposée par Facebook

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

Ainsi, en tant que programmeur paresseux (je devrais dire bon programmeur ^^), vous pouvez utiliser un équivalent (dans votre page) :

window.jqReady = function() {}

Et ajoutez en bas de votre layout, après jQuery include

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

6voto

Protector one Points 1546

Plutôt que d'attendre (ce qui se fait généralement en utilisant la fonction setTimeout ), vous pouvez également utiliser la définition de l'objet jQuery dans la fenêtre elle-même comme un crochet pour exécuter votre code qui s'appuie sur lui. Cela est possible grâce à la définition d'une propriété, définie à l'aide de la fonction 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

    }
  });
})();

4voto

Simon Points 558

Je n'aime pas trop les intervalles. Quand je veux différer jquery, ou n'importe quoi d'autre en fait, ça se passe généralement comme ça.

Commencez par :

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

Ensuite :

 <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>

Et enfin :

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

Ou la version la moins ahurissante :

<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>

Et dans le cas de l'asynchronisme, vous pourriez exécuter les fonctions poussées sur jquery onload.

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

Alternativement :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X