简体   繁体   中英

Why there exist error Uncaught ReferenceError: $ is not defined if add async?

My index like this :

...
<html >

<head>
    ...
    <script src="/scripts/myapp.min.js"></script>
    <script src="/scripts/myapp-themming.min.js"></script>

</head>

<body class="header-static">
    <div class="page-container">
        <!-- this is call header, navigaton, content, footer -->
    </div>

    <script type="text/javascript" src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
    <script type="text/javascript" src="/Content/assets/script/jquery-ui.min.js"></script>
    ...

    <script type="text/javascript">
        ...
    </script>
    <script>
        $(document).ready(function () {
            ...
        });
    </script>
</body>

</html>

If I test pages speed using gtmetrix. And gtmetrix recommendation for Defer parsing of JavaScript. So I try to add async like this :

<script src="/scripts/myapp.min.js" async></script>
<script src="/scripts/myapp-themming.min.js" async></script>

it showing following error,

Uncaught ReferenceError: $ is not defined

If I using defer , it make 3 error like this : Uncaught ReferenceError: $ is not defined , Uncaught TypeError: $(...).material_select is not a function , and Uncaught TypeError: $(...).select2 is not a function

How can I solve this error?

You have two errors as mentioned above, Uncaught ReferenceError: $ is not defined, Uncaught TypeError: $(...).material_select is not a function, and Uncaught TypeError: $(...).select2 is not a function

the first problem can be resolved by adding the following js file on the top before any other js as shown below

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js">
...
<script src="/scripts/myapp.min.js"></script>
<script src="/scripts/myapp-themming.min.js"></script>

Next Error is for select2 . For resolving this issue,add the following stylesheet and js file after jquery.min.js

<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.10/css/select2.min.css" rel="stylesheet" />

<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.10/js/select2.min.js">

First move the two scripts in the <body> into the <head> section at the top (above the 3 dots you have added). This is what @Nijin Koderi meant.

The important thing is making sure that jQuery is ABOVE everything else so it is loaded first.

Secondly - you can't just use async as mentioned in the other answer I gave as you will end up with a race condition.

The reason you get less errors with async is purely down to load speed of resources, you will find that with enough loads you will get different errors depending on which scripts download the fastest.

It is much easier while you are learning this to use defer (in fact I nearly always use defer unless you are loading megabytes of JS or your site needs JS within milliseconds to work)

To quote the answer I gave

The easiest way [to defer parsing of JavaScript] is to add defer attribute to each JavaScript request.

For better performance (difficult) I would recommend using async instead as this will start downloading sooner and activate each Script as soon as it is available.

However this often causes issues with 'race conditions' where scripts may load out of order (ie if you are using jQuery and another script loads before it that needs jQuery you will get an error).

Try defer first and if performance is good use that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM