Monday, September 17th, 2007
Sprinkle In Your JavaScript
<p>Jon Davis had a message for us:I’ll make this brief.
This is the latest in the client-side includes explosion that started with the colour purple.
Take a peak at the sprinkle.js that makes it happen.
Related Content:











You may use “class” or “id” attribute for div, because “src” is not a valid W3C attribute for DIV tag.
Port 880? That’s odd.
No Working Link
No Working Site
how can i see its a working idea ?
That code is scary. Here’s an example:
var attribs = el.attributes;
var i;
var j, d;
for (i=0; i<attribs.length; i++) {
if (attribs[i].name == "src") {
d = false;
for (j=0; j<attribs.length; j++) {
if (attribs[j].name == "csiLoadStatus" && (
attribs[j].value == "loading" ||
attribs[j].value == "loaded")) {
d = true;
break; // from nested loop
}
}
if (!d) {
csiLoad(el, attribs[i].value);
}
}
}
Isn't that about the same as this?
var src = el.getAttribute('src');
if( src ) {
var status = el.getAttribute('status');
if( status != 'loading' && status != 'loaded' )
csiLoad( el, src );
}
It’s not too useful… Why sprinkle? There are many, many frameworks with more possibilities. And this is not XHTML valid page.
“If you are unable to see content above, maybe you should turn Javascript on, or get a halfway decent web browser.”
Opera 9.x is as decent as they come. ;) Sprinkle didn’t support it, though.
In jQuery:
$(“textarea[src], div[src], span[src]“).each(function() {
$(this).load(this.src);
});
for all but inputs. If you want to support inputs too:
$(“textarea[src], input[src], span[src], div[src]“).each(function() {
var self = this;
$.get(this.src, function(data) {
if(self.tagName == “INPUT”) $(self).val(data);
else $(self).html(data);
});
});
i hope this was posted as a joke
Awesome, a piece of Javascript that’s invalid AND inaccessible at the same time. Good to see we’re making inroads with the whole “unobtrusive scripting” idea.
Not only that, but the code itself is pretty bad.
Hey gents,
give him a break… the idea behind it is valid… I´ll have a closer look at the code.
Sry just saw Yehudas jQ solution… nothing to add.
I’ll actually rate this, based on Yehuda’s three line jQuery alternative alone.
In Prototype:
//create element method ‘loadSrc’
Element.addMethods({
loadSrc: function(element, options){
element = $(element);
new Ajax.Updater(element, element.src||”, options);
return element;
}
});
//execute ‘loadSrc’ on queried elements
$$(‘textarea[src],div[src],span[src]‘).invoke(‘loadSrc’, options);
//add support for input elements
if(element.tagName == ‘INPUT’){
new Ajax.Request(element.src||”, {
method:’get’,
onSuccess:function(transport){
element.value = transport.responseText;
}
});
}
Can we make this an ongoing Ajaxian game – take long, bloated, scary javascript code from other projects and see how few lines we can re-create it with using jQuery/ProtoType/etc?
note: 100% serious, I’ve found it rather amusing, interesting (and increasing my desire to sit down and learn one of these frameworks) when I see X project/source posted, followed by the 3-line jQuery alternative in the comments :)
Great idea kaniz.
Tx jdalton!
Prototype 3 lines:
$$(’textarea[src],div[src],span[src]’).each(function(el){
new Ajax.Updater(el, el.src||”);
});
The core issue I see with this is that without javascript, it’s broken. A link to the HTML content (ie., the no-JS case) which is otherwise removed and replaced with the content of that link via JS would be more useful.
Hands up, who else remembers ?
In all fairness, the Sprinkle code does a lot more than the three-line jQuery or Prototype versions. But it seems to be doing more than it needs to – some of the options aren’t really necessary.
Here’s some more of the source code:
function csiGetInnerHtmlOfTag(str, tagName) {
if (str.toLowerCase().indexOf("<" + tagName) > -1 &&
str.toLowerCase().indexOf("</" + tagName + ">",
str.toLowerCase().indexOf("<" + tagName)) > -1) {
var startTagStart = str.toLowerCase().indexOf("<" + tagName);
var startTagEnd = str.indexOf(">", startTagStart);
var endTagStart = str.toLowerCase().indexOf("</" + tagName, startTagEnd);
var ret = str.substring(startTagEnd + 1, endTagStart - 1);
return ret;
} else return str;
}
That one function calls
str.toLowerCase()five times. It callsstr.toLowerCase().indexOf("<" + tagName)three times. It callsstr.toLowerCase().indexOf("</" + tagName + ">", str.toLowerCase().indexOf("<" + tagName))twice!Clearly some refactoring would be in order here. Or you could do the whole thing with one regular expression:
function getInnerHtmlOfTag(str, tagName) {
var match = str.match(
new RegExp( '<' + tagName + '[^>]*>(.*)</' + tagName + '>', 'i' ) );
return match ? match[1] : str;
}
I hate this comment system. No preview, no editing, a tiny narrow fixed width theme, and it screws up any source code I try to post!
Ajaxians, fix this thing. Kill it and get something that works. You should expect that people will want to post code in the comments, right?
Check my blog for an example of how you can have comments with good readable code formatting – in fact the same formatting as the posts themselves. Take this discussion for example:
http://mg.to/2006/01/25/json-for-jquery
If I can do it, you can do it. :-)
(Sorry, you wouldn’t be able to use my code “as is” because the site uses Drupal – but you’re welcome to use the code formatting part if you want to adapt it to WordPress – it’s based on the GeSHi code formatter with some tweaks of my own for the zebra striping and such.)
Hey guys,
Thx for the feedback on my Sprinkle. I totally agree that the code should be cleaned up. I just my idea was a cool one, even if it isn’t the most beautiful implementation around. :) I’ll likely do a lot of refactoring.
Jon
Thanks for not taking offense at our comments, Jon. You are a true gentleman. If I called your code “scary”, believe me, I used to write code that was much scarier!
I’m just kind of an inveterate code simplifier. Here’s one more for the road… :-)
if (antiCacheMethod == "querystring") {
var dt = new Date();
var dts = ""
+ dt.getFullYear()
+ dt.getMonth()
+ dt.getDate()
+ dt.getHours()
+ dt.getMinutes()
+ dt.getSeconds();
if (src.indexOf("?") == -1) src += "?nocachetimestamp=" + dts;
else src += "&nocachetimestamp=" + dts;
}
could be:
if (antiCacheMethod == "querystring") {
src +=
( src.match(/\?/) ? '&' : '?' ) +
'nocachetimestamp=' + (new Date).getTime();
}
Note that this also gives you a timestamp with “millisecond” resolution (actually around 15 milliseconds on many platforms), instead of the one second resolution in the original code.
I look forward to seeing your new streamlined revision… :-)
“The core issue I see with this is that without javascript, it’s broken. A link to the HTML content (ie., the no-JS case) which is otherwise removed and replaced with the content of that link via JS would be more useful. ”
Scott, how is this broken? That should work just fine. It just doesn’t work on the actual sprinklejs.com web site itself since the site doubles as a browser test. You can obviously populate the contents of your tag with HTML while adding src=”..” to the tag itself, so that its contents have HTML defaults and Javascripted replacements. I just chose not to do that on the actual web site.
Jon, that gets to the heart of some of the objections that a few commenters raised: The sprinklejs.com website doesn’t offer a good use case for the technology. In fact, the site is a better illustration of a case where you *shouldn’t* use this. Does the dynamic loading on this particular site give you anything that you couldn’t do with a straight-up HTML page? Especially considering that an HTML page would have several advantages:
* Indexable by search engines
* Works in any browser
* Works if JavaScript is disabled
* Faster loading
* Fewer hits on your server
I’m not saying there aren’t use cases where this approach has some benefit, just that the current sprinklejs.com page isn’t one of them. Put together a demo case where the dynamic loading actually offers some value, in fact enough extra value to overcome its inherent disadvantages, and then it will be easier to convince people of its merits.
Michael, I agree that while there are some cases where this would be ideal (literally it was for a quick sidebar navigation / advertisement component that we added to one of our magazine web sites), and several more places where it wouldn’t be ideal. The site does demonstrate where it wouldn’t be ideal.
.. *cough* and yes I should clean up sprinklejs.com to make it “more ideal”. The point is, that’s not the point. :)
I wrote a similar script using JQuery a while back. The JQuery implementation is about three lines of code. I just blogged about the script and included implementations for Prototype and several other JavaScript frameworks. The link is:
http://www.forgeniuses.com/?p=3
While this is an old thread, I still want to make it clear what my intentions were with sprinklejs.com. I am not trying to convince anyone to use this; rather, I had a need for this functionality, I didn’t want a big, bulk jQuery or Prototype support lib (3 lines of jQuery code, sure, with 48kb of support code!!), and so I sat down and produced it myself. I registered a domain name and put it out there to *share* it, not to sell myself or get rich and famous or compete with anyone.
So if you have the same need, great, enjoy! If you don’t, I don’t care!