Created
May 25, 2019 09:19
-
-
Save mkkeck/a1c58b979a616a6eddd7c29d7770b227 to your computer and use it in GitHub Desktop.
Function to queue jQuery in inline scripts, until jQuery is fully loaded async or via script injection.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*! | |
* Queue jQuery function calls until jQuery is fully loaded. | |
* | |
* This avoids "jQuery / $ is undefined" errors in inline scripts | |
* if jQuery is loaded asynchron or via script injection | |
* | |
* Copyright 2019, Michael Keck <https://github.com/mkkeck> | |
* Released under the MIT license | |
*/ | |
/* | |
* Example Usage: | |
* | |
* 1). Include this gist as an inline script in the <head> of your HTML document | |
* | |
* 2). Add follow script code for injecting jQuery (loading asynchron): | |
* | |
* // script injection | |
* !function(l, o, a, d, j, q) { | |
* j = o.createElement(a); | |
* j.src = d; | |
* j.async = true; | |
* // trigger on load | |
* j.onload = j.onerror = function() { | |
* j.onload = j.onerror = null; | |
* | |
* // the default name of the unqueue function is "$onLoaded" | |
* // check if the function window.$onLoaded is available | |
* if (/^f/.test(typeof l[ "$onLoaded" ])) { | |
* // call window.$onLoaded | |
* l[ "$onLoaded" ](); | |
* } | |
* }; | |
* q = o.getElementsByTagName(a)[0]; | |
* q.parentNode.insertBefore(j, q); | |
* }(window, document, "script", "path/to/jquery.min.js"); | |
* | |
* 3.) Usage in inline scripts: | |
* | |
* // document.ready, prefered and best way | |
* jQuery(function( $ ) { | |
* // Your jQuery code here, using the $ | |
* }); | |
* | |
* // document.ready, alternative 1 | |
* jQuery(document).ready(function( $ ) { | |
* // Your jQuery code here, using the $ | |
* }); | |
* | |
* // document.ready, alternative 2 | |
* jQuery(document).on("ready", function( $ ) { | |
* // Your jQuery code here, using the $ | |
* }); | |
* | |
* // window.load | |
* jQuery(window).load(function( $ ) { | |
* // Your jQuery code here, using the $ | |
* }); | |
* | |
* // window.load; alternative 1 | |
* jQuery(window).on("load", function( $ ) { | |
* // Your jQuery code here, using the $ | |
* }); | |
* | |
* 4). Notice: | |
* You can also use jQuery( window|document ).bind( ... ), but .bind() is | |
* deprecated since jQuery 3.0. | |
* See: https://api.jquery.com/category/deprecated/deprecated-3.0/ | |
*/ | |
/** | |
* @param {String} [$ready] Name of the function wich is applied to the global | |
* scope (window) for calling after jQuery is loaded; | |
* default: "$onLoaded" | |
* result: {Function} Window.$onLoaded(); | |
* | |
* @param {String} [$sym] Set your own alias / shortcut for jQuery, | |
* espacially usefull for jQuery.noConflict; | |
* default: "$" | |
* | |
* @param {Window} [win] Global scope; | |
* default: Window | |
* @type {Function} | |
*/ | |
(function($ready, $sym, win) { | |
/** @type {*|Window} */ | |
win = win || window; | |
/** | |
* @type {String} $ready; default: "$onLoaded" | |
*/ | |
$ready = $ready || "$onLoaded"; | |
/** | |
* @type {String} $sym; default: "$" | |
*/ | |
$sym = $sym || "$"; | |
var | |
/** | |
* @type {Document|Window} element; Store the used element (Window | Document) | |
* @private | |
*/ | |
element, | |
/** | |
* @type {Object} queueFn; Functions for the queue | |
* @private | |
*/ | |
queueFn, | |
/** | |
* @type {Array} queue; The queue to store jQuery calls | |
* @private | |
*/ | |
queue = [], | |
/** | |
* @type {Document} doc; jQuery needs a Document | |
* @private | |
*/ | |
doc = win.document, | |
/** | |
* @type {String} jQuery; The name of the library | |
* @private | |
*/ | |
jQuery = "jQuery", | |
/** | |
* @type {String} bind; Name for function "bind" | |
* @private | |
*/ | |
bind = "bind", | |
/** | |
* @type {String} ready; Name for function "ready" | |
* @private | |
*/ | |
ready = "ready", | |
/** | |
* boolean = is( string(value) [, RegExp(pattern) ] ); | |
* | |
* Checking typeof's | |
* | |
* @private | |
* @param {String} value | |
* @param {RegExp} [typof] | |
* @return {boolean} | |
*/ | |
is = function(value, typof) { | |
return !typof ? value !=="undefined" : typof.test(value); | |
}; | |
// only do it, when Window.jQuery is typeof "undefined" | |
if ( !is(typeof win[ jQuery ] )) { | |
/** @type {{q: q, load: load, ready: ready, on: on}} */ | |
queueFn = { | |
/** | |
* queueFn.p( function(handler), string(event), Window|Document); | |
* | |
* Push $.on(), $.bind(), $(document ...), $(window).load() to the queue | |
* | |
* @param {Function} handler | |
* @param {String} event | |
* @param {Window|Document} element | |
*/ | |
q: function(handler, event, element) { | |
queue.push((!event || event === ready) | |
? handler | |
: { e: element === win ? win : doc, b: event, h: handler } | |
); | |
}, | |
/** | |
* queueFn.on( string(event), function(handler) ); | |
* | |
* @param {String} event | |
* @param {Function} handler | |
*/ | |
on: function(event, handler) { | |
queueFn.q(handler, event, element); | |
}, | |
/** | |
* queueFn.load( function(handler) ); | |
* | |
* @param {Function} handler | |
*/ | |
load: function(handler) { | |
queueFn.q(handler, "load", win); | |
}, | |
/** | |
* queueFn.ready( function(handler) ); | |
* | |
* @param {Function} handler | |
*/ | |
ready: function(handler) { | |
queueFn.q(handler, ready, doc) | |
} | |
}; | |
/** @type {queueFn.on} queueFn.bind; Alias of queueFn.on for older jQuery versions */ | |
queueFn[bind] = queueFn.on; | |
/** | |
* Temporary Window.$ / Window.jQuery | |
* | |
* @type {Function} | |
*/ | |
win[ $sym ] = win[ jQuery ] = function(handler) { | |
if ( is(typeof handler, /^f/) ) { | |
return queueFn[ ready ](handler); | |
} | |
element = handler === win ? win : doc; | |
return queueFn; | |
}; | |
} | |
/** | |
* Callback function, when jQuery is fully loaded. | |
* Note: You have to call this function manually! | |
* | |
* @return {Window.$} | |
*/ | |
win[ $ready ] = function() { | |
var entry, lib; | |
if ( is(typeof win[ jQuery ].fn) ) { | |
// Get a copy of Window.$ / Window.jQuery | |
lib = win[ $sym ] = win[ jQuery ]; | |
bind = is(typeof lib.on) ? "on" : bind; | |
while( queue.length > 0) { | |
entry = queue.shift(); | |
if ( is(typeof entry, /^f/) ) { | |
lib(entry( lib ) ) | |
} | |
else { | |
(function(entry) { | |
if (entry.e && entry.b && entry.h) { | |
lib(entry.e)[ bind ](entry.b, function() { | |
entry.h( lib ); | |
}) | |
} | |
})(entry); | |
} | |
} | |
// Return Window.$ / Window.jQuery | |
win[ $sym ] = win[ jQuery ] = lib; | |
} | |
return win[ $sym ]; | |
}; | |
})( /*! "$onLoaded" */ ); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*! | |
* Queue jQuery function calls until jQuery is fully loaded. | |
* | |
* This avoids "jQuery / $ is undefined" errors in inline scripts | |
* if jQuery is loaded asynchron or via script injection | |
* | |
* Copyright 2019, Michael Keck <https://github.com/mkkeck> | |
* Released under the MIT license | |
*/ | |
!function(n,f,t){t=t||window;n=n||"$onLoaded";f=f||"$";function e(n,o){return o?o.test(n):"undefined"!==n}var u,i,r=[],c=t.document,d="jQuery",y="bind",a="ready";if(!e(typeof t[d])){(i={q:function(n,o,f){r.push(o&&o!==a?{e:f===t?t:c,b:o,h:n}:n)},on:function(n,o){i.q(o,n,u)},load:function(n){i.q(n,"load",t)},ready:function(n){i.q(n,a,c)}})[y]=i.on;t[f]=t[d]=function(n){if(e(typeof n,/^f/))return i[a](n);u=n===t?t:c;return i}}t[n]=function(){var n,o;if(e(typeof t[d].fn)){o=t[f]=t[d];y=e(typeof o.on)?"on":y;for(;0<r.length;){n=r.shift();e(typeof n,/^f/)?o(n(o)):function(n){n.e&&n.b&&n.h&&o(n.e)[y](n.b,function(){n.h(o)})}(n)}t[f]=t[d]=o}return t[f]}}(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment