HUD sans jQuery
Over at HUD I maintain a page that shows a bunch of RSS headlines in a columnar layout, so that is scales well between desktops, tablets and phones, with some imagery at the bottom. Recently, I “unified” the PHP and Javascript versions I maintain of that page (the layouts are now the same). Today I also removed the dependency on jQuery for the Javascript version, which is now the default for HUD. The script I used was a very old jQuery plugin, and I thought it good practice to replace that with the meanwhile improved Javascript. This of course required some puzzling, as I barely know Javascript, let alone jQuery.
The most significant thing that had to be replaced was $.ajax
. This function required me to learn the difference between JSON and JSONP. I use Yahoo’s YQL to convert RSS-feeds to a JSON object, and at first I was fiddling with XMLHttpRequest()
because that is what as the main replacement. After a lack of success, I learned that it doesn’t by default work between domains (Yahoo would need to whitelist my domain which they incomprehensibly haven’t). Then, I already forgot where but probably a Stackoverflow post, a brilliant mind shared with me the trick: YQL actually serves a JSONP object, which is simply wrapping the JSON you request (in this case: RSS headlines) in a callback function, which means no more than it calling the callback function you specify with the JSON object as argument. By adding that ‘script’ as a new element to the DOM, cross-domain borders are removed (for reasons unclear to me). I want to share how that is done:
var s = document.createElement('script');
s.type = 'text/javascript';
s.src = "https://somewhere/somescript?callback=somefunctionname";
var h = document.getElementsByTagName('script')[0];
h.parentNode.insertBefore(s, h);
Wow. Now I grasp more firmly why Javascript is a collection of neat workarounds. My second problem was that $.ajax
quietly expands ?
to a randomized callback function name, and both generates a JSONP-specific function and adds the name of that function as the callback function. Do you follow? I took me a while. Reminder that I am a Javascript virgin. Anyhoo, that little bit I now had to emulate, and of course, Javascript with its infinite flexibility eventually let me solve the issue. Note that the callback function must be available in global scope, so my first idea of a local function did not work. Eventually the solution crystallized:
var functionName = 'someprefix' + Math.floor(Math.random()*1000001);
window[functionName] = function(o){
//get JSON object by appending functionName to YQL URL
//handle JSON object 'o'
}
Later, I simplified also the insertion of feed-html by having the function create an child-object to some div in my HTML:
var id = 'somechildname' + Math.floor(Math.random()*1000001)
var childelement = document.createElement("ul");
childelement.id = id;
var parentelement = document.getElementById("parentid");
parentelement.appendChild(childelement);
You can see that I am a quick study. I guess this is the Javascript way (or: the stubborn I-don’t-want-to-use-jQuery way. Or: the n00b-way). What matters is that now I can simply add feeds by writing koppen('https://url/to/rss')
and it will add this feed, in order of function call to koppen
(which is Dutch for ‘heads’. Get it?), under the div
I specified, if it can be obtained from Yahoo. Of course, the full source is available at HUD; just press CTRL-U
to view the page’s source.