Issue in loading fbOptions.js and core.js

Page: 1

Author Post
Member
Registered: Feb 2019
Posts: 4
I am using floatbox 8.0.0. On some pages floatbox do not show up because it fail to load [fbOptions.js] and [core.js]. I noticed, whenever it fail, the path formed for those 2 JS files are incorrect. In [floatbox.js] I noticed below line of code (line#37).

scriptUri = parseUri( select( 'script', 0, -1 ).src ),

Looking deeper in [select] method it looks like it fetches all "script" elements on the page in an arrary. It assumes that the last element in this array is the script element for [floatbox.js]. Pages that have issues in loading [fbOptions.js] and [core.js] seem to be because the the last element in the script array is not for [floatbox.js].

I might be asking very dump question here. I do not know if I am missing anything but, I wonder why it assumes that the last element in the array will always be for [floatbox.js]? Could you please help me understand this?

I noticed that newer version of floatbox like version 8.1.3 allow to pass [ScriptPath] through [fbOptions]. I need to explore that option more, but that might also not help in my scenario.
Administrator
Registered: Aug 2008
Posts: 3382
Reading/parsing/loading of a document is always interrupted when a script element is encountered while that script is loaded, parsed and executed. If, for example, in any script you add
console.log( window.document.documentElement.innerHTML )
you will see that the document has at that point been constructed only up to the currently executing script. Therefore, regardless of where the script element appears in the page source, it will necessarily be the last script (in fact, the last element) in the document object tree while it is executing.

If, as you report, floatbox.js is not picking up the correct path to fbOptions and core, then it is almost certain that you are using some sort of lazy-load mechanism that fetches floatbox.js after DOMContentLoaded, hence after the document is fully constructed, thus after the time when the script is the last element in the document. The ability to specify a path to the floatbox.js file in a fbOptions object on the loading page is there precisely so that floatbox can find its originating folder when lazy-loaded and the script src attribute is of no use. Strictly for convenience, it can also provide an array of 'ready' functions to run after floatbox is loaded, and that would otherwise be run through fb.ready() calls.
fbOptions = {
scriptPath: '/path/to/floatbox.js',
ready: [ funk1, funk2 ]
};


My preferred approach is to exclude floatbox.js from any script lazy-loaders or bundlers, let it load normally inline during initial document construction, and let it use its own mechanism to lazy-load fbOptions.js and core.js. I would go so far as to say, ditch any other lazy-loaders and use floatbox.js to bootstrap all your scripts with its fb.require() function. floatbox.js has a very small and efficient footprint (4.3KB gzipped) and there's no gain to be had by duplicating its already-present 'require' capabilities with another script.

Finally, use version 8.2.2 please. I believe it is mature, complete, solid and golden, it may well be the last ever update, and it certainly sheds any dot-zero stink from earlier version 8 releases. Importantly, it is now official Floatbox Support policy that support is available only for 8.2.2 (or later if there ever is a later). Problem reports from other versions will be responded to with "upgrade to 8.2.2 and then we can talk".

Cheers...
Member
Registered: Feb 2019
Posts: 4
You are correct, I do a ajax call, at least on few pages, because of which the script element for [floatbox.js] is not the last item in the array.

One suggestion would be to change

scriptUri = parseUri(select('script', 0, -1).src)

to

scriptUri = parseUri(select('script[src*="floatbox.js]"]', 0, -1).src)
Administrator
Registered: Aug 2008
Posts: 3382
Also worth mentioning here:

If lazy-loading Floatbox, you can minimize the count of fetched files by merging the floatbox files into one monolith.

Start with the fbOptions and its scriptPath as given above, then fbOptions.js (perhaps minified), then floatbox.js, then core.js. If using a language other than English, specify that 2-letter language code in fbOptions:global:language and append the corresponding language file to the bottom of the monolith. Call the resultant file anything you like (with a .js extension) and lazy-load the whole thing after DOMContentLoaded with no subsequent follow-on fetches by the floatbox code.

However, I really can't recommend this approach, nor suggest that there is any advantage to lazy-loading floatbox.js. People like to do this because of a belief that it might speed page load time. Floatbox.js does two things - initialize the floatboxed stuff on the page and lazy load its modules. Delaying the initial load delays the time when the page is initialized and ready for action and presents content to the user with links intended for floatbox behaviour which instead just navigate normally or don't respond at all.
Administrator
Registered: Aug 2008
Posts: 3382
A minor bug fix update is going to be posted RSN, so I took the opportunity to incorporate your suggestion. It's modified a bit:
scriptUrl = parseUrl( pageOptions.scriptPath ||
( select( 'script[src*="floatbox.js"]' )[ 0 ] || select( 'script', 0, -1 ) ).src ),

This will handle folks who rename floatbox.js, and yes, I've encountered that in the wild before.
Member
Registered: Feb 2019
Posts: 4
That works for me, thanks.

Page: 1