I'm merging the use of the YouTube iFrame API and jQuery loaded in through a script tag that has the defer
flag set. The defer flag must be set as the client has a perfect Google page insight score and wishes to maintain that score.
The YouTube API, upon being fully loaded and ready for use, immediatley calls a function that I define onYouTubeIframeAPIReady
. It will then later call onPlayerReady
upon the player being fully loaded and rendered.
I wish to use jQuery in this function, but just using jQuery inside the onPlayerReady function will be creating a race condition (hoping the jQuery library has finished loading by the time onPlayerReady gets called).
It occured to me a workable solution would be to use the onPlayerReady function to set a variable before calling a function that tests for both the player and jQuery. Another function sets a variable upon jQuery being ready and calls the same test function.
I have some code that works, but the part that checks for jQuery seems messy to me, and also introduces a small amount of extra unneccessary delay. I was wondering if anyone knows of a better way to run something the instant jQuery bees available. Basically, are there callbacks for jQuery being available built into the library itself?
My current code is as follows:
var ready = {
'jquery': false,
'youtube' false
},
testJQueryLoaded;
testJQueryLoaded = function() {
if(typeof jQuery == 'undefined') {
window.setTimeout(function() {
testJQueryLoaded();
}, 25);
return;
}
ready.jquery = true;
postLibraryLoad();
};
testJQueryLoaded();
function onYouTubeIframeAPIReady() {
// Stuff
};
function onPlayerReady() {
ready.youtube = true;
postLibraryLoad();
};
function postLibraryLoad() {
if(!ready.jquery || !ready.youtube) {
return;
}
// More stuff
};
I'm merging the use of the YouTube iFrame API and jQuery loaded in through a script tag that has the defer
flag set. The defer flag must be set as the client has a perfect Google page insight score and wishes to maintain that score.
The YouTube API, upon being fully loaded and ready for use, immediatley calls a function that I define onYouTubeIframeAPIReady
. It will then later call onPlayerReady
upon the player being fully loaded and rendered.
I wish to use jQuery in this function, but just using jQuery inside the onPlayerReady function will be creating a race condition (hoping the jQuery library has finished loading by the time onPlayerReady gets called).
It occured to me a workable solution would be to use the onPlayerReady function to set a variable before calling a function that tests for both the player and jQuery. Another function sets a variable upon jQuery being ready and calls the same test function.
I have some code that works, but the part that checks for jQuery seems messy to me, and also introduces a small amount of extra unneccessary delay. I was wondering if anyone knows of a better way to run something the instant jQuery bees available. Basically, are there callbacks for jQuery being available built into the library itself?
My current code is as follows:
var ready = {
'jquery': false,
'youtube' false
},
testJQueryLoaded;
testJQueryLoaded = function() {
if(typeof jQuery == 'undefined') {
window.setTimeout(function() {
testJQueryLoaded();
}, 25);
return;
}
ready.jquery = true;
postLibraryLoad();
};
testJQueryLoaded();
function onYouTubeIframeAPIReady() {
// Stuff
};
function onPlayerReady() {
ready.youtube = true;
postLibraryLoad();
};
function postLibraryLoad() {
if(!ready.jquery || !ready.youtube) {
return;
}
// More stuff
};
Share
Improve this question
asked Sep 11, 2017 at 15:26
ScootsScoots
3,1032 gold badges24 silver badges35 bronze badges
1
- 1 no, there is no such event. you could however append the script tag via javascript and listen for its events. – Kevin B Commented Sep 13, 2017 at 20:16
4 Answers
Reset to default 3 +50As suggested by @KevinB you can utilize load
event of specific <script>
element
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis./ajax/libs/jquery/3.2.1/jquery.min.js" defer></script>
<script>
const dojQueryStuff = (el, params) => this.jQuery(el, params).appendTo("body");
</script>
<script>
document
.querySelector("script[src$='3.2.1/jquery.min.js']")
.onload = event => {
console.log(event.target.src);
dojQueryStuff("<div>", {
html: "jQuery version: " + this.jQuery().jquery + " loaded"
});
}
</script>
</head>
<body>
</body>
</html>
I suppose .ready()
would do.
$(document).ready(function(){
ready.jquery = true;
postLibraryLoad();
});
You may know but..
1. This wouldn't throw execution error before jQuery is loaded, and
2. This would execute once and only when jQuery is ready.
So I suppose this code below works:
var ready = {
'jquery': false,
'youtube': false
};
$(document).ready(function(){
ready.jquery = true;
postLibraryLoad();
});
function onYouTubeIframeAPIReady() {
// Stuff
}
function onPlayerReady() {
ready.youtube = true;
postLibraryLoad();
}
function postLibraryLoad() {
if(!ready.jquery || !ready.youtube) {
return;
}
// More stuff
}
Assuming onYouTubeIframeAPIReady()
is triggered at somewhere else firstly, this code should run postLibraryLoad()
up to twice either after youtube is ready or jQuery is ready, ultimately running // More stuff
only when the both is ready.
edit: format
edit: added explanation
I know this may seems odd, but if that's the small code you are worried about, then why don't you add it inside the jQuery library, at the bottom. and call the onYouTubeIframeAPIReady()
. you can also remove this part ready.jquery = true;
pletely.
I'm having this exact issue right now. The way I'm going to deal with it is by doing the following.
<script>
// Custom Event Polyfill for IE11
if ( typeof window.CustomEvent !== "function" ) {
function CustomEvent ( event, params ) {
params = params || { bubbles: false, cancelable: false, detail: undefined };
var evt = document.createEvent( 'CustomEvent' );
evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail );
return evt;
}
CustomEvent.prototype = window.Event.prototype;
window.CustomEvent = CustomEvent;
}
</script>
Then at the end of jQuery file loading which I'm doing from the server instead of via Google I'm adding this
<script>
// Start of jQuery script
(function (global, factory) {
// jquery stuff in here
})( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
// ALL OF THE jquery CODE IN HERE ....
return jQuery;
});
// I Add this at the end.
var jQueryLoadedEvent = new CustomEvent('jQueryLoaded');
document.dispatchEvent(jQueryLoadedEvent);
</script>
Then I'll wrap my own scripts with this.
<script>
document.addEventListener('jQueryLoaded', function (e) {
(function ($) {
console.log('All of my code in here. Or some of it, I can wrap more code with the same event listener elsewhere.');
console.log('jQuery version: ', $.fn.jquery);
})(jQuery);
});
</script>