I'm confused as to why putting my YouTube tracking code into an IIFE stops it working.
My understanding was that IIFEs run instantly, so why is there a difference between including a script with just bare js vs an IFEE?
Here's my plain JS, which works correctlly:
if ( 0 < ga_options.youtube.length ) {
var tag = document.createElement( 'script' );
tag.src = '//www.youtube.com/iframe_api';
var firstScriptTag = document.getElementsByTagName( 'script' )[0];
firstScriptTag.parentNode.insertBefore( tag, firstScriptTag );
function onYouTubeIframeAPIReady() {
scroll_events.register_youtube_videos();
}
}
However, when I wrap it in an IIFE, like below, it no longer works (no tracking events are fired). I am trying to use an IIFE as part of a restructuring of existing code into self-contained units.
Please could someone explain what I am doing wrong? I have considered scope and tried using var tag
and var firstScriptTag
outside of the IIFE, but still no success.
gaEventsVideoTracking = (function(){
window.console.log( "why no youtube tracking?" );
if ( 0 < ga_options.youtube.length ) {
tag = document.createElement( 'script' );
tag.src = '//www.youtube.com/iframe_api';
firstScriptTag = document.getElementsByTagName( 'script' )[0];
firstScriptTag.parentNode.insertBefore( tag, firstScriptTag );
function onYouTubeIframeAPIReady() {
scroll_events.register_youtube_videos();
}
}
})();
The function onYouTubeIframeAPIReady
gets called by the script loaded from YouTube's servers.
Since you are using a function declaration to define it, it is locally scoped to the IIFE. This means it is not a global and thus not available for YouTube's script to call.
You can explicitly make it a global.
Add var onYouTubeIframeAPIReady;
at line one (outside the IIFE) and then put onYouTubeIframeAPIReady =
in front of the function declaration to make it a function expression and assign it to the global variable.