My JavaScript book is out! Don't miss the opportunity to upgrade your beginner or average dev skills.

Thursday, September 21, 2006

JavaScript benchmark for while and for loop

It's just a page to test directly differents loops and respective times with blue "winners" too :)

If you have a really old (or slow) PC please don't visit the page.

If you visit the page and everything stops, close the page and wait few seconds.

Loops Benchmark: http://www.devpro.it/examples/loopsbench/

Wednesday, September 20, 2006

anonymous function to add simple events

This post shows as is possible to set prototypes with anonymous functions.
This one shows a simple anonymous function application example, a fake addEventListener.
We often use directly the method with the document element, it's simple and fast, then often our preferred way to implement an event.
I'm talking about this code

document.getElementById("myId").onclick =
function(){alert("hello")};


DOM and standars like this method to add an event

document.getElementById("myId").addEventListener(
"click",
function(){alert("hello")},
false
);


But IE doesn't implement addEventListener method (what a news ...)

document.getElementById("myId").attachEvent(
"onclick",
function(){alert("hello")}
);


The attachEvent has different problems, it isn't a standard method (then IE and few other browsers supports that) and the scope inside the callback is not the element.
This code, for example, doesn't work as expected:

document.getElementById("myId").attachEvent(
"onclick",
function(){alert(this.className)}
);


I've implemented the addEventListener in my big dollar function but often developers doesn't like "big" external libraries (scriptacolous as prototype and Dojo are some exceptions).
That's why I'm writing this simple function to add an event directly to an element, using generic on* event names.

function addSimpleEvent(
obj, // the object (i.e. window, document, element)
type, // the type (i.e. "onload", "onmouseover", "onclick")
callback // the callback (i.e. function(){alert(this)})
) {
obj[type] = (function(base){ // anonymous function
return function(evt){ // function called on event
if(!evt)evt=window.event; // event for IE browsers
if(base)base.call(this,evt); // old function, if defined
callback.call(this,evt); // callback
}
})(obj[type]) // old defined (or not) function
};

This function uses anonymous function to preserve old event (base variable), if presents, and calls every callback with the element scope (using call).
This is an example:

// imagine that other script did it ...
onload = function(){alert("Hello 1")};

// addSimpleEvent function
function addSimpleEvent(obj,type,callback) {
obj[type] = (function(base){return function(evt){
if(!evt)evt=window.event;
if(base)base.call(this,evt);
callback.call(this,evt);
}})(obj[type])
};

// you can add one, two or more events
addSimpleEvent(window, "onload", function(){alert("Hello 2")});
addSimpleEvent(window, "onload", function(){alert("Hello 3")});


// if you want, you could create another function to add multiple events of same type
function addMultipleEvents() {
for(var i = 2, j = arguments.length; i < j; i++)
addSimpleEvent(arguments[0], arguments[1], arguments[i]);
}

// and use it in this way
addMultipleEvents(window, "onload",
function(){alert("Hello 4")},
function(){alert("Hello 5")},
function(){alert("Hello 6")}
);

Just test this script to view this sequence of alerts

Hello 1
Hello 2
Hello 3
Hello 4
Hello 5
Hello 6

What's about compatibility ? Every browser that supports call and doesn't loose base variable during execution, then IE 5.5+, FireFox, Opera, KDE, Safari and many others.

I hope this little function will be usefull for you window, document, or element common events.

anonymous function prototype

There are several scripts that use anonymous functions and we often use them as regulars.
Is there a way to have different or dedicated prototypes for this kind of function ?

Step 1, what is anonymous function ?
The "original" anonymous function is returned from the global Function object.

var myFunc = new Function("a", "b", "c", "return a + b + c;");
alert(myFunc(1,2,3)); // number 6

myFunc is a function with all Function prototypes or native methods and with the same constructor of a function.
Then myFunc is absolutely a function, but wich kind of function is it ? Exactly this one:

function anonymous(a, b, c) {
return a + b + c;
}

What's that ? That's a function that exists but you can't modify, get, or extend anyway because each new Function will produce a different referer for a different anonymous function.

(new Function).prototype.isAnonymous = true;
alert((new Function).isAnonymous); // undefined

You can try in a different ways creating for example a personal anonymous function, but the result will be the same ...

var anonymous = new Function;
(new Function).prototype.isAnonymous = true;
alert((new Function).isAnonymous); // undefined

// other way

function anonymous(){};
anonymous.prototype.isAnonymous = true;
alert((new Function).isAnonymous); // undefined

That's becaus, as I've just said, every anonymous instance is different from every other.
With FireFox you should view this difference using toSource Obect native method.

function anonymous(){};

var realanonymous = new Function;

alert([
anonymous.toSource(), // function anonymous() {}
realanonymous.toSource(), // (function anonymous() {})
anonymous === realanonymous // false
]);

As you can see, those parentheses are the key to understand the anonymous function.




Step 2, parentheses and virtual scope
At this point we know that an anonymous functions cannot have dedicated prototypes and aren't like regular functions too.
In some script you can see the use of parentheses to call runtime a function or to create one.
This code, for example, is an unobtrusive way to add a personal String prototype.

String.prototype.toArray = (function(base){
return base || function(){return this.split("")}
})(String.prototype.toArray);

alert("test".toArray()); // t,e,s,t

Let me explain this few lines of code.
If some script, before this one, has just defined a String.prototype.toArray or browser has a native String.toArray function, the anonymous function created using parentheses and directly called with (String.prototype.toArray) that accepts, if present, the base function, will assign to that prototype old version (base) or, if base is not defind, our prototype function (function(){return this.split("")}).
The closed anonymous function is then a special function and its really usefull to solve a lot of problems.
This is only a little example but I think you used anonymous functions every day with every scripts ;)
Since the scope inside parentheses "magically disappear", but neither for itsself nor for its internal scope, we can think that those kind of functions are exactly anonymous.

var myAnonymous = (function anonymous(){}),
realAnonymous = (new Function);

alert([
myAnonymous, // (function anonymous(){})
realAnonymous, // (function anonymous(){})
myAnonymous === realAnonymous, // false
myAnonymous.toSource() === realAnonymous.toSource()
// true !!!
]);


Step 3, how to create a dedicate prototype
JavaScript is Object Oriented and each function is an object, then why I couldn't use "special" anonymous functions as an object ?
That's why I've created a simple solution to have customizable anonymous functions, every one will be different from every other, but everyone will have our dedicate prototypes.
This is the concept function

// anonymous explicit function
function anonymous() {

// prototype to prototype,
// this function copy each a prototype (p) to other (b) function
function p2p(p,a,b) {

// using prototype for b too isn't a good solution (imho)
// because only new anonymous will has these prototypes
for(var k in a[p])b[k] = a[p][k];
return b;
};

// we need arguments and its length plus a genric array
var l = arguments.length, a = [];

// if argument is not one or its not a function
if(l !== 1 || arguments[0].constructor !== Function) {

// create the string ([arguments[N],...,arguments[0]])
while(l)a.push("arguments[".concat(--l,"]"));

// then reverse ...
a.reverse();

// ... to assign anonymous function to arguments 0
eval("arguments[0]=new Function(".concat(a.join(","),")"));
}

// return its "prototyped" version of anonymous function
return p2p("prototype", arguments.callee, arguments[0]);
};

The major difference from native new Function(arguments) is that my anonymous function accpets an anonymous function too.
Here there's a complete test to view some application.

// anonymous explicit function
function anonymous() {
function p2p(p,a,b) {
for(var k in a[p])b[k] = a[p][k];
return b;
};
var l = arguments.length, a = [];
if(l !== 1 || arguments[0].constructor !== Function) {
while(l)a.push("arguments[".concat(--l,"]"));
a.reverse();
eval("arguments[0]=new Function(".concat(a.join(","),")"));
}
return p2p("prototype", arguments.callee, arguments[0]);
};

// common Function prototype
Function.prototype.isFunction = true;

// only anonymous prototype
anonymous.prototype.isAnonymous = true;

// first test --------------------------------------
// new anonymous creation with the same sintax of new Function
test = anonymous("str", "alert(str)");

// just few checks
alert([
"" + anonymous.isAnonymous, // undefined, anonymous is a function
"" + test.isFunction, // true, test is a function
"" + test.isAnonymous // true, test is an anonymous function
]);

test("Hello World!"); // Hello World! [then test works perfectly]
// _________________________________________________



// second test --------------------------------------
// common function declaration using anonymous
test = anonymous(function(str){alert(str.toUpperCase())});

// just check it
alert([
"" + test.isFunction, // true, test is a function
"" + test.isAnonymous // true, test is an anonymous function
]);

test("Hello World!"); // HELLO WORLD! [then test works perfectly]
// _________________________________________________



// third test --------------------------------------
alert(anonymous(function(){}).isAnonymous); // true
// _________________________________________________



// final test --------------------------------------
anonymous(function(a){alert(a + arguments.callee.isAnonymous)})("Anonymous ? ");
// true
// _________________________________________________

Just a look at the last test, where is used arguments.callee instead of "this".
That's simply why the "this doesn't exists" inside the function ("this" inside a function is the window object).
That's all :)

Tuesday, September 19, 2006

studying google adsense code ...

PLEASE READ ME FIRST
This post is "a joke", then I hope you'll look at this as an ironical and hilarious post about google scripts and google developers that are really more skilled than me :)
I've found an error on my "best" script then I've looked for problem inside adsense code because with its code my script generates strange redirect errors (adsense code escapes objects or numbers too without string casting while my encodeURIComponent implementation didn't care about toString() method befor parsing ... I know, I've done a stupid thing :P )


studying code ...
3 days ago I've posted about an unknown problem using my JSL at the top of this blog.

The first point is ... sorry blogspot, you didn't cause any problem to JSL

The secondo point is this one: google adsense ... have you seen the code ?
To find the problem and then the solution I've downloaded adsense code to look inside that after a "manual code beautifier operation".
That's what I think about adsense code:
  • absolutely "undebuggable", to be lightweight (about 7Kb in a local file, maybe compressed on-line with gz, then 2Kb) variables and function names are really hard to understand
  • contains few errors, Opera as FireFox show everytime something inside the js console
  • it doesn't use a "perfectly" optimized code

Let's analyze adsense JS code, using this page as referer: google adsense beautified code.

The good thing is that all adsense code is inside an anonymous function, then every other script on the page will not be modified ... every but another google adsense script, because the use of window inside the script allows itself to create a big list of window.google_* variables.
This shouldn't be a problem, but if you use a script that does a for in loop with the window oblect, you need to rememeber that every /^google_/.test(param) should be leave as is.
It's time to view the internal function code, starting from optimizzations.
As you can read on many lines, for example on line 6, every if / else if / else uses curly brackets ... even when it's not necessary (every single operation after the condition).
But if you look at the line 295, someone uses correctly an "if" without braces ... who did this ? Maybe not the same developer ?
Since it's correct even with single line funtions, to optimize this script a lot of braces should be removed, adding where we need a ";" char.

// example with function B (starting from line 5)
function B(b){
if(typeof encodeURIComponent=="function")
return encodeURIComponent(b);
else
return escape(b);
}

Then I've just removed 2 chars from the size of the script but hey ... that function should be different!

// another example with function B
function B(b){
return typeof encodeURIComponent=="function"?encodeURIComponent(b):escape(b)
}

Another example is on line 153, where there is a ternary operation for var h but not for var q.

var h=a.google_ad_region==b?"":a.google_ad_region,q=j?j.indexOf("_0ads")>0:false;

After few lines (159) we can read another "unoptimized" piece of code that should be wrote in one line.

a.google_num_0ad_slots=!a.google_num_0ad_slots||a.google_num_0ad_slots+1>1?1:a.google_num_0ad_slots+1;

However I wonder when this piece of code should be usefull because google_num_0ad_slots is not present in this script, then it's maybe defined from other scripts.
If this is true or not, the if,else and then if does something like this:
if google_num_0ad_slots is not defined, or is null or is 0, google_num_0ad_slots should be 1, in every other case should be google_num_0ad_slots + 1 then it should be 0 if google_num_0ad_slots is less than zero.

if(!a.google_num_0ad_slots||++a.google_num_0ad_slots>1)a.google_num_0ad_slots=1;

These "if/else and then if again" I've just optimized are in different lines of the script but in some cases there is only an if else (i.e. 170 whre there's any "greater than 1" check)
In these cases the code should be

if(!a.google_num_ad_slots)a.google_num_ad_slots=0;
++a.google_num_0ad_slots;

or should be this one

if(!++a.google_num_ad_slots)a.google_num_ad_slots=1;

only if parameter is always initialized with 0 or greater value.

Another little optimizzation should be done on function F (line 73).
Since adsense code optimizzation is based on short var names I think that repeat for a lot of times the same object param prefix is not so good as a dedicated params array should be:

function F(b){
var a=[
"ad_frameborde","ad_format","page_url","language","gl","country","region","city","hints","safe",
"encoding","ad_output","max_num_ads","ad_channel","contents","alternate_ad_url","alternate_color",
"color_bg","color_text","color_link","color_url","color_border","color_line","adtest","kw_type",
"kw","num_radlinks","max_radlink_len","rl_filtering","rl_mode","rt","ad_type","image_size","feedback",
"skip","page_location","referrer_url","ad_region","ad_section","bid","cpa_choice","cust_age","cust_gender",
"cust_interests","cust_id","cust_job","cust_u_url"
],l=a.length;
while(l)b["google_"+a[--l]]=null;
}

In this way all properties are simple to add or to remove from the list, and "b.google_" is present just one time.
However if an optimized while should be slower to parse with a really big array, using o.param1=o.param2=o.paramN=null instead of "=a" for each param should be the same thing.

AdSense script uses a lot of returns in-function, that is a method I don't like very much (but it's only my opinion and using only one return isn't a better way to write functions).
For example there's a "special" function I've seen that's not good enought for me, it is the x function (line 293).

function x(b,a){
var d=a.documentElement,r=z(b,a,"location"),g=1,e=1;
if(!r&&b.google_ad_width&&b.google_ad_height){
if(b.innerHeight){
g=b.innerWidth;
e=b.innerHeight
}
else if(d&&d.clientHeight){
g=d.clientWidth;
e=d.clientHeight
}
else if(a.body){
g=a.body.clientWidth;
e=a.body.clientHeight
}
r=(e>2*b.google_ad_height||g>2*b.google_ad_width)
}
return !r
}

If you look at the original version you can view that if z is true (then r in my version), function returns false.
Then if !r (when r is not true) it's possibile to do other operations inside the first if condition.
At the end of the first if you can assign a boolean value without the if and the second in-function return.
Then if r is true, the final return value is false. It's true for the first check as for the second, then in every other cases, when r is not true, returned value will be true (not false).

This is the way I usually like to return a boolean value from a function or method using only a single return (cleaner, imho) at the end of the function.

We are going to the end of this post, there's only another function I've not understand ... the C function (line 286).
As you can see C function recieves 3 parameters, any of these is used, A function is called and true value is returned.
Do you think it's usefull ? I think that A function, that doesn't have any input parameters and doesn't return anything, should return true value and should be used directly on line 325.

b.onerror=A;

... adding return true on A function ... then anyone doesn't need the C function (but maybe it was created for future implementations).

The absolute last thing I want to tell to google AdSense script developers is this one:
why do you optimize in this way the code but you use "var" for every temporary function variable ?

Look at the line 319, inside the function E ... wasn't better something like ...

var b=window,a=document,d=a.location,g=a.referrer,e=null;

??? it's the same with A, D and other functions ...

Monday, September 18, 2006

portable and rewrote onmousewheel function

I did a simple version of onmousewheel, then I add JSL and $DOM objects dependencies, then I've came back to single portable version without dependencies that's simpler than first one :D

Concept:
onmousewheel isn't a window or document event, onmousewheel is a generic Element event. While a generic event as onclick, onmouseover, onmouseout is called only above the element, onmousewheel will be called only above the element too, that's all!

No more double events (onmouseover that activates onmousewheel and onmouseout that deactivates onmousewheel) ... just the event.


/**
* function onmousewheel,
* onmousewheel(element:Object [, callback:Function]):Void
* @param Object window, document or DOM.element to use with callback
* @param Function callback function with element scope (.call(...)) and delta wheel value as single parameter
* @return Void
*/
function onmousewheel(element, callback) {

// @author Andrea Giammarchi [http://www.devpro.it/]
// @license MIT [http://www.opensource.org/licenses/mit-license.php]
// @credits Adomas Paltanavicius [http://adomas.org/javascript-mouse-wheel/]

function __onwheel(event) {
var delta = 0;
if(event.wheelDelta) {
delta = event.wheelDelta / 120;
if(window.opera)
delta = -delta;
}
else if(event.detail)
delta = -event.detail / 3;
if(delta)
callback.call(element, delta);
if(event.preventDefault)
event.preventDefault();
event.returnValue = false;
return false;
};

if(element.addEventListener && !window.opera)
element.addEventListener("DOMMouseScroll", __onwheel, false);
else
element.onmousewheel = (function(base){return function(evt){
if(!evt) evt = window.event;
if(base) base.call(element, evt);
return __onwheel(evt);
}})(element.onmousewheel);
};


And here you can view the always updated version or the example page.

too much simple DOMContentLoaded solution ?

Dean Edwards closed comments in this page (sorry Dean) , but I wonder if there is a real example page where this alternative way to implement DOMContentLoaded doesn't work as expected (please post me one !!!).

My simple solution is this one, anonymous function with multiple callbacks after document.body is not undefined.


(function(){if(document.body){for(var i=0;i<arguments.length;i++)arguments[i]();}else setTimeout(arguments.callee,1)})
(initLightbox, otherFunc, somethingElse, init);



Just 2 simple lines of code, but for some reason it shouldn't work correctly in some case.

Then, while my test page doesn't fail this method, at least with my browsers, I'd like to know when this way shouldn't work correctly or when this way should work (I always prefere to reduce JS size then if generic cases work correctly with this method to implement DOMContentLoaded I'll prefere this one).

Can anyone explain me what's up when this method fail ? Thank you.

Sunday, September 17, 2006

unoubtrusive presentation ?

Flash teachs us to add a skip intro button inside presentations.

I was joking with big dollar function and FakeDOM (or FastDOM ?) alpha libraries and I've thought to add a view intro button, using a page block with a div and calling an image to present this site.

Here you can try to view the result, do you like it ?

Saturday, September 16, 2006

Big dollar $ function to solve standards

Maybe the best and elegant way to get one or more document element as you know.

The $ function is used from a lot of JS developers, it's simple, fast and allow us to reduce scripts size (forget document.getElementById).

Then that's my idea: why we can't use $ to add element standards ?

Every element that's grabbed with $ function should be parsed by function to improve Element standards ... and why not, to add special features for each element.

Here there's an example: big $ function where you can view my first standard implementation, addEventListener and removeEventListener for every browser.

It's not based on attachEvent because attachEvent doesn't works with element scope (this is not the element inside an event listner function ... and it's terrible !!!) and this alpha version manages correctly whellscroll too for IE6, FireFox or Opera 9.

This function will be extended to add a lot of standard Element methods but only if this is a good solution or a good idea, then I'm waiting for some reply :)

Finally, here there's alpha code for a big $ function

function $() {
// (C) Andrea Giammarchi - alpha release
if(!window.$_$)
window.$_$ = {
elementsList: [],
eventsList: {
DOMActivate :"ondomactivate",
DOMAttrModified :"onattrmodified",
DOMCharacterDataModified:"oncharacterdatamodified",
DOMFocusIn :"ondomfocusin",
DOMFocusOut :"ondomfocusout",
DOMMouseScroll :"onmousewheel",
DOMNodeInserted :"onnodeinserted",
DOMSubtreeModified :"onsubtreemodified",
NodeInsertedIntoDocument:"onnodeinsertedintodocument"
},
$A: function(obj) {
var i = obj.length, result = [];
while(i)result.push(obj[--i]);
return result
},
elementsManager: function(element, eventName, callback, listener) {
var i = 0;
if(!this.elementsList.some(function(obj, j){var b = obj.node === element; if(b)i = j; return b}))
i = this.elementsList.push({node:element,events:{}}) - 1;
callback(this.elementsList[i], eventName, listener);
},
attachEvent: function(element, eventName, listener) {
if(!element.events[eventName])
element.events[eventName] = [];
if(element.events[eventName].indexOf(listener) < 0)
element.events[eventName].push(listener);
element.node[eventName] = function(event) {
element.events[eventName].forEach(
function(listener){
if(event) listener.call(element.node, event);
else listener.call(element.node, window.event);
}
)
}
},
detachEvent: function(element, eventName, listener) {
if(element.events[eventName])
element.events[eventName] = element.events[eventName].filter(function(lst){return lst!==listener});
},
temporaryMethod: function(methodName, element, base, eventName, listener, useCapture) {
methodName.push(element[methodName[0]]);
element[methodName[0]] = base;
element[methodName[0]](eventName, listener, !!useCapture);
element[methodName[0]] = methodName.pop();
},
eventsManager: function(addEvent, element, base, eventName, listener, useCapture) {
var methodName = addEvent ? ["addEventListener", "attachEvent"] : ["removeEventListener", "detachEvent"];
if(this.eventsList[eventName]) {
if(base && !window.opera)
this.temporaryMethod(methodName, element, base, eventName, listener, useCapture);
else
this.elementsManager(element, this.eventsList[eventName], this[methodName[1]], listener);
}
else {
if(base)
this.temporaryMethod(methodName, element, base, eventName, listener, useCapture);
else
this.elementsManager(element, "on".concat(eventName), this[methodName[1]], listener);
}
}
};
var elements = window.$_$.$A(arguments);
elements.forEach(function(element, i){
if(element.constructor === String)
elements[i] = document.getElementById(element);
if(window.$_$.elementsList.indexOf(elements[i]) < 0) {
window.$_$.elementsList.push(elements[i]);
elements[i].addEventListener = (function(base) {
return function(eventName, listener, useCapture) {
window.$_$.eventsManager(true, this, base, eventName, listener, useCapture);
}
})(elements[i].addEventListener);
elements[i].removeEventListener = (function(base) {
return function(eventName, listener, useCapture) {
window.$_$.eventsManager(false, this, base, eventName, listener, useCapture);
}
})(elements[i].removeEventListener);
}
});
return elements.length === 1 ? elements[0] : elements
};

blogspot modified my library

It's true ... JSL cannot be included at the top of this blog space (howevwer thanks for this free blog system).

Try yourself, include JSL inside head tag and .... WOW, your blog will "disappear".

That's another reason to base libraries or every kind of script on JSL that doesn't modify anything, if present.

JSL is an unobtrusive way to implement JS 1.6, not the unique way to use some personal prototypes.

To add my JSHighLighter, that requires JSL, in this blog I had to include external JS sources at the bottom of the blog model ... come on blogspot, trash your String.replace or encodeURIConponent implementation and use JSL :D


P.S. I don't know what was modified, I saw a redirect to an invalid url created by some blogspot script.

Friday, September 15, 2006

Why we need a JavaScript Standard Library

JavaScript 2.0 is on the air but in a lot of js oriented sites I can see every day show often the same, obvious or boring prototypes to normalize some old browser before every kind of different solution for every different problem.

Yesterday, for example, I've read about a "revolutionary" way to search a value inside an array, using an "horrible" Object solution.

If you read comments you could see that Array has a native, standard, prototype called indexOf that does exactly what that blog was talking about.

Well, why do you like to spend your time for these things ?

You like that because you don't know all JavaScript 1.6 objects methods or you don't use FireFox to develop your code and you don't have a low level code normalizer library.

However, one of the first comments shows the simplest solution for the problem, indexOf, but shows another Array.prototype normalizer function.

This is just one example of all posts that you can find on the net and everytime someone posts a Something.prototype normalizer solution for that problem, for that library.

Maybe in your 3rd part page scripts you have at least 2, 3 or more equal prototypes that normalize this, that or other library ... or recreate always the same result with a different name.

Don't you have enought ? Don't you care about sum of every script size ?

I wonder why JSL hasn't been linked from any "javascript specialist site" because to write a standard code, using for example JSLint, isn't enought to produce good, fast or optimized code.

I've talked about my JSL to Dojo developers too, to resolve a lot of common JS portability problems and to resolve encodeURIComponent or decodeURIComponent top-level function portability that are quite perfect only with JSL, as String.replace with function as second argument is.
Dojo developers didn't care about JSL ... they don't need another normalizer library (but they have a propetary normalizer library ... that doesn't make JS more standard for every other lib in a 100Kb of packed code lobrary ... ).

Prototype has its normalizer proto too but these aren't standard.
Array.each is not standard (while JS 1.6 has Array.forEach, that's a standard method), indexOf is not complete (and I havn't seen the String.indexOf implementation) ... then why rewr everytime the same normalizer prototype ?

Why increase every library with its normalizer prototype when JavaScript 1.6 has at least one of every normalizer proto used inside every library ?

Do you think this is a good way to depends everytime from each different library ?
Do you think your library is the "only cool one" and then every developer should learn a different (but same) implementation of every different library normalizer prototypes ?

We don't like IE because it doesn't respect standards, every JS library I've seen doesn't respect ECMA standards too.

Why don't you use JSL and then ECMA Standards for JS 1.6 ?

When finally all browsers will be compatible at least with JS 1.6, remove JSL will be a simple step while using prototype or other libraries dedicated implementation of "un-standard" ECMA will not be possible.

Don't you like this point of view ? Don't you like standards ?

Do you need some example ?


// original prototype versionfunction
$() {
var elements = new Array();
for (var i = 0; i < arguments.length; i++) {
var element = arguments[i];
if (typeof element == 'string')
element = document.getElementById(element);
if (arguments.length == 1)
return element;
elements.push(element);
}
return elements;
}

// JSL and prototypefunction
$() {
var elements = $A(arguments).forEach(function(element, i){
if(element.constructor === String)
elements[i] = document.getElementById(element);
});
return elements.length === 1 ? elements[0] :elements
}

// getElementsByClass from Top 10 JavaScript Function (Dustin Diaz)
function getElementsByClass(searchClass,node,tag) {
var classElements = new Array();
if ( node == null )
node = document;
if ( tag == null )
tag = '*';
var els = node.getElementsByTagName(tag);
var elsLen = els.length;
var pattern = new RegExp('(^|\\s)'+searchClass+'(\\s|$)');
for (i = 0, j = 0; i < elsLen; i++) {
if ( pattern.test(els[i].className) ) {
classElements[j] = els[i];
j++;
}
}
return classElements;
}

// JSL versionfunction getElementsByClass(searchClass,node,tag) {
var classElements = [],
els = (node || document).getElementsByTagName(tag || "*"),
pattern = new RegExp('(^|\\s)'+searchClass+'(\\s|$)');
for(var i = 0, j = els.length; i < j; i++)
classElements.push(els[i]);
return classElements.filter(function(element){
return pattern.test(element.className)
})
}

// JSL and $A prototype versionfunction getElementsByClass(searchClass,node,tag) {
var pattern = new RegExp('(^|\\s)'+searchClass+'(\\s|$)');
return $A((node || document).getElementsByTagName(tag || "*")).filter
(function(element){return pattern.test(element.className)
})
}

// inArray from Top 10 JavaScript Function (Dustin Diaz)
Array.prototype.inArray = function (value) {
var i;
for (i=0; i < this.length; i++) {
if (this[i] === value) {
return true;
}
}
return false;
};

// unusefull inArray implementation with JSL
Array.prototype.inArray = function (value) {
return this.indexOf(value) !== -1
}

// maybe more usefull inArray (has) version with multiple arguments
Array.prototype.has = function() {
var i = arguments.length, result = [];
while(i)
result.push(this.indexOf(arguments[--i]) !== -1);
return result.every(function(e){return e})
};// ...


Finally, if a lot of developers think that top 10 JS funcs should be inside a common.js, why they don't think that a low-level lib as JSL is should be a must before every every top-ten common.js ?

It's a single file, as a common.js file should be, it's lightweight, it's to develop every kind of medium or high level lib or code using standards, it's a must to write code for FireFox and use it with every other browser .... then why don't you like my JavaScript Standard Library ?

My Blog (finally!)

[eng]
Hello guys, welcome in my blog space :)

What about ? JavaScript, PHP, C#, Python, XHTML, CSS and some special comment for some of my scripts/codes/libraries (http://www.devpro.it/)

See you bloggers!


[ita] Finalmente ho deciso di spostarmi su un circuito bello e pronto, do l'addio momentaneo al vecchio blog http://www.3site.it/blog/ che per problemi di tempo e di ... tempo, non sono mai riuscito a sviluppare per intero, qui invece รจ tutto mooooolto comodo ;)