Wednesday, September 26, 2007

What's wrong with new IEContentLoaded solution?

Update
This post talk about old implementation posted in Ajaxian before this one.

After some interesting comment, posted by Diego Perini, it seems that His last proposal is logically the best We can use today to solve this IE problem.

What I missed in my one is an onreadystatechange alternative to be sure function is called before onload one.

In my case this is not a problem but if You use third party code libraries it should be a big problem.
At this point Diego solution seems to be perfect for every case so just use them and thank You Diego and every other developer that helped Him to find this cool, portable, efficient solution :-)


---------------------------------------------


The solution proposed in this page to solve in another way DOMContentLoaded IE problem, ir really interesting.

I didn't test them so much but I suppose this is a valid alternative.

I didn't know doScroll behaviour too, so it's quite a surprise for me and I'm happy if this will work as expected simply because alternatives uses a script with a particular source string that one day should be a problem for every secure site: src="://"

ok guys, but what's wrong with this solution?


Firsto point is that it's logic is quite bugged.

In fact, since this line:

tempNode = null;

should be useful to free memory, I can't understand why author choosed to put them inside try.

try, as You know, works as a sentinel ... when a single error occurs, catch is instantly called and every other piece of code inside try will never be executed.

If the goal was to free memory (but You'll read here that's even not important) it should be wrote after catch statement:

var tempNode = document.createElement('document:ready');
try {
tempNode.doScroll('left');
alert('window.onDocumentReady()');
}catch (err){
setTimeout(arguments.callee, 0);
};
tempNode = null;


The other point is wrote inside first linked page:
“… A few methods, such as doScroll, require the primary document to be completely loaded. If these methods are part of an initialization function, they should be handled when the ondocumentready event fires. …”


Well, at this point, if this is true ... why do you create an element each timeout?

(function (){
if(!document.uniqueID && document.expando) return;
try {
document.firstChild.doScroll('left');
alert('window.onDocumentReady()');
}catch (err){
setTimeout(arguments.callee, 0);
}
})();


At this point You can see that solution is even simpler than original one.
document.firstChild, if You know how to write an (x)HTML page, is never a scrollable element.

This mean that You can use it directly, instead of create every time a new element.

The last point is that the best secure way to use a piece of code only with IE it to use conditional comment while last point is that a setTimeout with 0 as delay is never respected by browser because 0 means the minimum possible delay and not 0!

/*@cc_on
(function(){
try{
document.firstChild.doScroll('left');
alert("window.onDocumentReady()")
}catch(e){
setTimeout(arguments.callee, 10)
}
})();
@*/


Is that's all? none

You can use conditional comment to create an window.onReady portable and cross-browser function:

onReady = (function(ie){
var d = document;
return ie ? function(c){
var n = d.firstChild,
f = function(){
try{
c(n.doScroll('left'))
}catch(e){
setTimeout(f, 10)
}
}; f()
} :
/webkit|safari|khtml/i.test(navigator.userAgent) ? function(c){
var f = function(){
/loaded|complete/.test(d.readyState) ? c() : setTimeout(f, 10)
}; f()
} :
function(c){
d.addEventListener("DOMContentLoaded", c, false);
}
})(/*@cc_on 1@*/);

onReady(function(){

alert("Hello DOM");

});


That should be packed in few bytes:

onReady=(function(ie,d){d=document;return ie?
function(c){var n=d.firstChild,f=function(){try{c(n.doScroll('left'))}catch(e){setTimeout(f,10)}};f()}:/webkit|safari|khtml/i.test(navigator.userAgent)?
function(c){var f=function(){/loaded|complete/.test(d.readyState)?c():setTimeout(f,10)};f()}:
function(c){d.addEventListener("DOMContentLoaded", c, false)}
})(/*@cc_on 1@*/);

onReady(function(){

alert("Hello DOM");

});

window.onReady(function(){

alert("Hello one more time");

});


Seems cool?

No comments:

Post a Comment