I am building a javascript widget that should load asynchronously.
Problem is that there can be more than 1 of these widgets on the page and that the widget should be initialized by sending it an option array via {}.
What is the best way to accomplish this? I heard that simply setting onload or onreadystatechange does not work in all browsers.
I've checked out the digg widget, but I can't really comprehend what they're doing, could anyone take a look at that?
Here's some of their code:
(function () {
var s, s1, diggWidget = {
id: "digg-widget-1282651415272",
width: 300,
display: "tabbed"
};
if (window.DiggWidget) {
if (typeof DiggWidget == 'function') {
new DiggWidget(diggWidget);
} else {
DiggWidget.push(diggWidget);
}
} else {
DiggWidget = [diggWidget];
s = document.createElement('SCRIPT');
s.type = 'text/javascript';
s.async = true;
s.src = 'http://widgets.digg.com/widgets.js';
s1 = document.getElementsByTagName('SCRIPT')[0];
s1.parentNode.insertBefore(s, s1);
}
})();
So, if the DiggWidget is already available (loaded earlier due to multiple instances), it makes a new widget if DiggWidget is a function, otherwise DiggWidget is used as an array and the current settings are pushed to it.
First, why would DiggWidget ever be a function?
If the widget is the only one (or first), the script tag is added asynchronously, no callbacks are defined.
Then, looking at widgets.js they do this:
At the top:
(function () {
var A;
if (window.DiggWidget) {
if (typeof DiggWidget != "function") {
A = DiggWidget
} else {
return
}
}
At the bottom:
if (A) {
while (A.length) {
new DiggWidget(A.shift())
}
}
Now I don't quite understand this. Is DiggWidget (the array) available to that .js ? It's in a anonymous function. So if I include such a script twice, wouldn't DiggWidget be a new instance every time?
Or am I completely in the wrong on this? Sorry if so. If there's any better methods to have a callback with multiple instances of the script, please do tell.
It will become a function when the asynchronous script loads and executes
Yes,
window.DiggWidget
is global so it's available to that script.The way the widget works is rather simple.
If the
DiggWidget
script has not been loaded yet, thenwindow.DiggWidget
will not be a function. Initially it will be an undefined variable so the else blockexecutes and defines it as an array. From now onwards and until the widget script loads, it will be defined as an array.
Now until the
DiggWidget
script loads asynchronously, keep pushing all initialization objects{..}
to an array of the same name -window.DiggWidget
.When the script is loaded, before it overtakes the global
DiggWidget
variable it sees the objects in that array, and safely records it somewhere else. Then takes over the DiggWidget name, loops through each object, and initializes the widget for each.Here's the full embed code annotated with comments.
User code
Widget code (at the top)
(at the bottom)