0

Wordpress loads jQuery automatically. I want to use it, but I get:

jQuery is not defined

This is because various plugins mess with the ordering of scripts. So there's no guarantee that my script will load AFTER jQuery is loaded. So if it loads before, I get that error.

Can I wrap my script in something that waits for jQuery to load, and then executes my script?

Notes

  • I don't want to manually load jQuery, because then I'll break various plugins... I must let Wordpress load it as usual
  • I'm not a PHP person, so I don't want to hack the theme... I just want to wrap my script in a cross-browser "jquery waiting script"
lonix
  • 14,255
  • 23
  • 85
  • 176
  • See also [wait for jQuery loaded](https://stackoverflow.com/questions/7486309/how-to-make-script-execution-wait-until-jquery-is-loaded) – Adder Nov 12 '19 at 09:25
  • @Adder Thanks. But that talks about using `defer`, which I cannot control as Wordpress controls jquery, and about document ready which is not relevant because jquery is not yet loaded. – lonix Nov 12 '19 at 09:28

3 Answers3

3

IMHO when 'load' is triggered you can use jQuery:

window.addEventListener('load', (event) => {
  // your code
});
Andrew
  • 373
  • 2
  • 15
  • I was thinking of doing exactly this because it's so straightforward / easy... But do you know if it's got good cross browser support? In my experience when something is so simple it's because the older nasty browsers don't support it :) – lonix Nov 12 '19 at 09:31
  • 1
    Yes it has very good browser support, please see: https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event You can also use `window.onload = function() { /* your code */ };` – Andrew Nov 12 '19 at 09:36
2

All functions in window.deferAfterjQueryLoaded will be runned after jQuery is defined, so if you push all your inizializations in window.deferAfterjQueryLoaded you can be sure that they will be runned after jQuery

<script>
    if (!window.deferAfterjQueryLoaded) {
        window.deferAfterjQueryLoaded = [];

        //delete Object.defineProperty; //add this if you want to check the support
        if (typeof (Object.defineProperty) === "function") {
            Object.defineProperty(window, "jQuery", {
                set: function (value) {
                    window.setTimeout(function () {
                        $.each(window.deferAfterjQueryLoaded, function (index, fn) {
                            fn();
                        });
                    }, 0);
                    Object.defineProperty(window, "jQuery", {value: value});
                },

                configurable: true
            });
        } else {
            nIntervId = window.setInterval(function () {
                if (typeof (jQuery) !== "undefined") {
                    $.each(window.deferAfterjQueryLoaded, function (index, fn) {
                        fn();
                    });
                    clearInterval(nIntervId);
                }
            }, 10);
        }
    }
    window.deferAfterjQueryLoaded.push(function () {
        (function ($) {
            console.log("After jquery is loaded");
        })(jQuery);
    });

</script>
<script>
    window.deferAfterjQueryLoaded.push(function () {
        (function ($) {
            console.log("After jquery is do something else");
        })(jQuery);
    });
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

You can read more abount Object.defineProperty, you can check the cross browser support here

angel.bonev
  • 2,154
  • 3
  • 20
  • 30
  • 1
    Thanks - looks interesting, I'm testing it now...Do you know whether this has cross browser support? – lonix Nov 12 '19 at 09:26
  • I've added a link so you can check it, I try to make some changes to the snippet , so you can cover browsers that don't support Object.defineProperty – angel.bonev Nov 12 '19 at 09:35
  • I don't think it is needed you have a polyfill at the end of page https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperties – angel.bonev Nov 12 '19 at 09:40
  • I have changed the snippet, jquery 3.3.1 is using Object.defineProperty so I've changed to 1.11.1 – angel.bonev Nov 12 '19 at 09:54
0

Maybe this helps:

$j = jQuery.noConflict();

Then use $j

Tom

Uklove
  • 509
  • 3
  • 9
  • The problem is jQuery is not even loaded yet - it's not a noconflict issue. – lonix Nov 12 '19 at 09:25
  • Ok. I had this error (not defined) sometimes und solved it like this. But usually I don`t move jQuery around. – Uklove Nov 12 '19 at 09:27
  • 2
    Yes in that case it's because Wordpress runs jquery in noconflict mode, so you must use `jQuery` instead of `$`. But that assumes jQuery is already loaded, so it solves a related but different problem. – lonix Nov 12 '19 at 09:29