81 votes

Comment différer Javascript en ligne?

J'ai le code html suivant:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/blazy/1.8.2/blazy.min.js" defer></script>
    <script src="https://code.jquery.com/jquery-2.1.4.min.js" integrity="sha256-8WqyJLuWKRBVhxXIL1jBDD7SDxU936oZkCnxQbWwJVw=" crossorigin="anonymous" defer></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lightbox2/2.9.0/js/lightbox.min.js" defer></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous" defer></script>
    <!-- 26 dec flexslider js -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/flexslider/2.6.3/jquery.flexslider.min.js" defer></script>
    <script defer>
    (function($) {
        $(document).ready(function() {
            //do something with b-lazy plugin, lightbox plugin and then with flexslider
        });
    })(jQuery);
    </script>
</head>
<body>
</body>
</html>

J'obtiens une erreur, en disant: jQuery n'est pas défini. Maintenant, même si je supprimer reporter à partir de mon code JS inline, il dit que jQuery n'est pas défini. Pour une raison que j'ai garder les plugins jQuery dans la tête et garder mon code JS inline. Ma question est:

  1. Pourquoi ne pas le Javascript en ligne du code reportés lorsqu' defer attribut est présent sur elle?

  2. Est-il un moyen d'imiter le reporter le problème sur mon inline code Javascript? Je peux mettre qu'à la fin de la balise body, si nécessaire.

142voto

trincot Points 10112

Les scripts avec l' defer attribut de la charge dans l'ordre où elles sont indiquées, mais pas avant que le document lui-même a été chargé. En tant que defer n'a pas d'effet sur script balises à moins de disposer de l' src attribut, le premier script qui est exécuté est votre script en ligne. Donc, à l'époque jQuery n'est pas chargé.

Vous pouvez résoudre ce problème de deux façons au moins:

  • Mettre votre script en ligne dans un .js le fichier de référence et avec un src d'attribut (en plus de l' defer de l'attribut auquel vous déjà eu il y a), ou

  • Laissez votre script en ligne d'attente pour le document et le report de scripts à charger. L' DOMContentLoaded événement se déclenche lors de ce qui s'est passé:

    <script>
        window.addEventListener('DOMContentLoaded', function() {
            (function($) {
                //do something with b-lazy plugin, lightbox plugin and then with flexslider
            })(jQuery);
        });
    </script>
    

NB: à noter que dans ce dernier cas $(document).ready(function() n'est pas comprise, pas plus, car ce serait d'attendre pour le même événement (DOMContentLoaded). Vous pourrait toujours inclure comme vous l'avez fait dans votre code original, mais alors jQuery serait tout simplement d'exécuter la fonction de rappel immédiatement, ce qui ne fait pas de différence pratique.

52voto

Brook Jordan Points 31

Vous pouvez créer un fichier crypté en Base64 URL du script et le mettre dans la src!

<script src="data:text/javascript;base64,YWxlcnQoJ0hlbGxvIHdvcmxkIScpOw=="
        defer>
</script>

J'ai construit un test rapide pour le voir en action. Vous devriez voir une alerte avec Hello world! dernier s' defer travaille:

<script defer>
  alert('Why no defer?!?');
</script>

<!-- alert('Hello world!'); -->
<script src="data:text/javascript;base64,YWxlcnQoJ0hlbGxvIHdvcmxkIScpOw=="
        defer></script>

<script>
  alert('Buh-bye world!');
</script>

Le faire manuellement est un peu compliqué donc, si vous avez le luxe de la compilation de votre code HTML d'une certaine façon (Guidon, Angulaire, etc.) alors que cela aide beaucoup.

Je suis actuellement à l'aide:

<script src="data:text/javascript;base64,{{base64 "alert('Hello world!');"}}"
        defer>
</script>

9voto

Jai Points 23908

De MDN docs:

reporter
Cette valeur de l'attribut est utilisé pour indiquer au navigateur que le script est destiné à être exécuté après que le document a été analysée, mais avant de mettre le feu DOMContentLoaded. Le reporter de l'attribut doit être utilisé uniquement sur des scripts externes.

Il s'agit d'une IIFE (Immédiatement appelé la Fonction de l'Expression) qui sera exécuté avant le DOM est disponible. Alors, dans ce cas jQuery n'est pas défini, car il n'est pas dans les DOM.

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