Handling code which relies on jQuery before jQuery is loaded

前端 未结 10 996
挽巷
挽巷 2020-12-08 06:31

I\'d like to follow the general guideline of putting all JavaScript at the very bottom of the page, to speed up loading time and also to take care of some pesky issues with

相关标签:
10条回答
  • 2020-12-08 07:10
    function jQueryGodot(code)
    {
        if (window.jQuery)
        {
            code(window.jQuery);        
        }
        else
        {
            if (!window.$)
            {
                window.$ = { codes: [] };
                window.watch('$', function(p, defered, jQuery) {
                    jQuery.each(defered.codes, function(i, code) {
                        code(jQuery);
                    });
                    return jQuery;
                });
            }
    
            window.$.codes.push(code);
        }
    }
    
    jQueryGodot(function($) {
        $('div').html('Will always work!');
    })
    

    Working example on JSFiddle.

    Code passed to jQueryGodot function will always be executed no matter if it is called before or after jQuery is loaded.

    The solution relies on Object.watch which requires this polyfill (660 bytes minified) in most of the browsers: https://gist.github.com/adriengibrat/b0ee333dc1b058a22b66

    0 讨论(0)
  • 2020-12-08 07:11

    Simple use pure javascript version of $(document).ready();:

    document.addEventListener("DOMContentLoaded", function(event) { 
        //you can use jQuery there
    });
    
    0 讨论(0)
  • 2020-12-08 07:12

    How about:

    <script>
        window.deferAfterjQueryLoaded = [];
        window.deferAfterjQueryLoaded.push(function() {
            //... some code that needs to be run
        });
    
        // ... further down in the page
    
        window.deferAfterjQueryLoaded.push(function() {
            //... some other code to run
        });
    </script>
    
    <script src="jquery.js" />
    <script>
        $.each(window.deferAfterjQueryLoaded, function(index, fn) {
            fn();
        });
    </script>
    

    This works because every script here is completely blocking. Meaning the creation of the deferAfterjQueryLoaded array and all functions being created and pushed to that array occur first. Then jQuery completely loads. Then you iterate through that array and execute each function. This works if the scripts are in separate files as well just the same way.

    If you ALSO want DOMReady to fire you can nest a $(function() {}) inside of one of your deferAfterjQueryLoaded functions like such:

    window.deferAfterjQueryLoaded.push(function() {
        $(function() {
            console.log('jquery loaded and the DOM is ready');
        });
        console.log('jquery loaded');
    });
    

    Ultimately, you should really refactor your code so everything is actually down at the bottom, and have a system conducive to that model. It is much easier to understand everything occurring and more performant (especially if you have separate scripts).

    0 讨论(0)
  • 2020-12-08 07:16

    I've wrote simple js code for handle such cases: https://github.com/Yorkii/wait-for

    Then you can use it like this

    waitFor('jQuery', function () {
       //jQuery is loaded
       jQuery('body').addClass('done');
    });
    

    You can even wait for multiple libraries

    waitFor(['jQuery', 'MyAppClass'], function () {
       //Both libs are loaded
    });
    
    0 讨论(0)
  • 2020-12-08 07:17

    The best way I have found is to write the code in a function and call the function after jquery is loaded:

    function RunAfterjQ(){
    // Codes that uses jQuery
    }
    
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
    <script type="text/javascript">
        RunAfterjQ();
    </script>
    

    Update: For master pages, you can define an array to push functions in the head of the master page:

    var afterJQ = [];
    

    then at the bottom of master page run all the functions pushed in to this array:

    <script type="text/javascript" src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
    <script type="text/javascript">
        for(var i = 0; i < afterJQ.length; i++) afterJQ[i]();
    </script>
    

    Everywhere that you need to use javascript that relies on jQuery and is before jQuery is defined just push it in to this array:

    afterJQ.push( function() { 
        // this code will execute after jQuery is loaded.
     });
    
    0 讨论(0)
  • 2020-12-08 07:17

    I have this same problem, but with a ton of files, I use headjs to manage the loading, it's only 2kb so there isn't really a problem, for me anyway, of putting in the header. Your code then becomes,

    head.ready(function(){
      $...
    });
    

    and at the bottom of the page,

    head.js('/jquery.min.js');
    
    0 讨论(0)
提交回复
热议问题