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

Friday, June 29, 2007

A simple JvaScript way to change element color

function gradient(id, start, end, speed, prop, callback){
var style = id.style || document.getElementById(id).style,
i = setInterval(function(){
for(var j = 0; j < 3; j++)
start[j] = gradient.run(start[j], end[j], speed);
style[prop] = gradient.color(start);
if(String(start) === String(end)) {
clearInterval(i);
if(typeof callback === "function")
callback(id);
}
}, 20);
start = gradient.rgb(start);
end = gradient.rgb(end);
speed = speed || 10;
prop = prop || "color";
return i;
};
gradient.color = function(c){return "#".concat(gradient.hex(c[0]), gradient.hex(c[1]), gradient.hex(c[2]))};
gradient.hex = function(rgb, c){return (c = rgb.toString(16)).length === 1 ? "0".concat(c) : c};
gradient.norm = function(c){return (c = c.substring(1)).length < 6 ? "".concat(c, c) : c};
gradient.rgb = function(c){return [parseInt((c = gradient.norm(c)).substr(0,2), 16), parseInt(c.substr(2,2), 16), parseInt(c.substr(4,2), 16)]};
gradient.run = function(x, y, speed) {return x < y ? Math.min(x + speed, y) : Math.max(x - speed, y)};


It's bytefx style and it could be used, for example in these ways:
onload = function(){
var div = document.createElement("div");
div.id = "test";
div.appendChild(document.createTextNode("Hello Gradient !"));
document.body.appendChild(div);
gradient("test", "#000000", "#FFFFFF", 10, "color", function(id){
gradient(id, "#FFFFFF", "#000000", 20, "backgroundColor", function(id){
gradient(id, "#FFFFFF", "#676767", 5)
})
});
};


... or in a Flash RollOver/Out style:
onload = function(){
var div = document.createElement("div");
div.id = "test";
div.appendChild(document.createTextNode("Hello Gradient !"));
document.body.appendChild(div);
div.colors = ["#000000", "#ABABAB"];
div.bgcolors = ["#FFFFFF", "#000000"];
div.newGradient = function(gradients){
if(this.gradients) {
clearInterval(this.gradients[0]);
clearInterval(this.gradients[1]);
};
this.gradients = [gradient.apply(null, gradients[0]), gradient.apply(null, gradients[1])];
};
div.onmouseover = function(){
this.newGradient([
[this.id, this.colors[0], this.colors[1]],
[this.id, this.bgcolors[0], this.bgcolors[1], 10, "backgroundColor"]
])
};
div.onmouseout = function(){
this.newGradient([
[this.id, this.colors[1], this.colors[0]],
[this.id, this.bgcolors[1], this.bgcolors[0], 10, "backgroundColor"]
])
};
};

Have fun with grandients and colors :-)

Wednesday, June 27, 2007

JSOMON, a JSON Evolution !


Have You never thought to send object methods too?
Have You never thought to drive completely your client side application from server?
Did You never try to save functions, callbacks or methods using JSON?
This is a new client/server interaction way for your Web 2.0 applications, this is JSOMON!
Another joke? Another experiment? Well, probably, but JSOMON is just ready to be tested, used and why not, to be better if You have some interesting features to add or modify and I'm waiting for your feedbacks.

Have fun with JSOMON!

Monday, June 18, 2007

FireFox 3 Password Manager? Well, check You password security :-)

This simple function returns a short number from 0 to 9, for a total of 10 points, to verify security level of your choosed password.

Score is evaluated in two different parts: one for the password length and one for character used for that password (different and alpha numeric, upper/lower case is better!).

This version is quite better than older one showed in this post: Unobtrusive Password Security Level Form

So have fun with password and take care your security :-)


function PasswordSecurityLevel(pass){
var level = 0,
length = pass.length,
re = PasswordSecurityLevel,
check = [re.all.test(pass), re.alu.test(pass), re.num.test(pass)],
i, chars, key;
switch(true){
case length > 15: level++;
case length > 11: level++;
case length > 7: level++;
case length > 5: level++;
break;
};
if(re.oth.test(pass))
level++;
if(check[0] && check[1] && check[2])
level++;
if((check[0] && check[1]) || (check[0] && check[2]) || (check[1] && check[2]))
level++;
if(level > 5) {
for(i = 0, chars = {}; i < length; i++)
chars[pass.charCodeAt(i).toString()] = true;
i = 0;
for(key in chars)
i += chars.hasOwnProperty(key) ? 1 : 0;
switch(true){
case i > 9: level++;
case i > 7: level++;
break;
};
};
return level;
};
PasswordSecurityLevel.num = /[0-9]/;
PasswordSecurityLevel.all = /[a-z]/;
PasswordSecurityLevel.alu = /[A-Z]/;
PasswordSecurityLevel.oth = /[^a-zA-Z0-9]/;

Saturday, June 16, 2007

Simple setTimeout / setInterval extra arguments IE fix

One of the coolest thing of Internet Explorer is that even version 7 doesn't respect timeouts or intervals creation functions as every other browser does!

I'm talking about extra parameters, that we need to pass inside a "temporary" (not for GC) extra function to use closures and to have same result.

Here is an example:

// i need an interval that check a variable ...
// ... and this is the way we usually do that ...
var i = setInterval((function(start){
return function(){
if(new Date - start > 990) {
alert("about 1 second: ".concat(new Date - start));
clearInterval(i);
}
}
})(new Date), 20);


Well done, two functions for our browser and boring unelegant way to code.

With FireFox, Opera, Safari and other more standard browsers, we should send directly extra arguments after delay interval.

setInterval(callback, delay, param1, param2, ..., paramN);

This means at least two things:
1 - we don't need to create a function wrapper to send arguments to callback
2 - we don't need to write many bytes to send parameter that need to be wrapper arguments that need to be sent to callback

A lot of developer uses string mode to solve this problem:
setTimeout("callback()", 20);

but as You know, eval is evil and we always prefere don't use them every time we can.

In this case, we should use "stupid" string evaluation to solve an Internet Explorer unfeaure ... but do we really need to code in this way?

Nope, and this is my simple proposal:

/*@cc_on
(function(f){
window.setTimeout =f(window.setTimeout);
window.setInterval =f(window.setInterval);
})(function(f){return function(c,t){var a=[].slice.call(arguments,2);return f(function(){c.apply(this,a)},t)}});
@*/

Of course, a conditional comment to call that anonymous function only with IE browser, every other will use native setTimeout or setInterval function without problems.

Please note that usage of window.setSomething, instead of direct setSomething assignment is a must, because if You remove window from left side IE will tell You that operation is not valid while if You remove window from righ side, IE simply will never do anything with those two functions.

About IE Performances?
A bit slower intervals, it's obvious, but why should we care about a browser that allow us to changes its native functionality with just a simple trick like that?

I don't know if someone has just talked about this problem and this solution but I hope this one will be useful for your next code.

Oooops, I forgot first example? Here it is ;-)
var i = setInterval(function(start){
if(new Date - start > 990) {
alert("about 1 second: ".concat(new Date - start));
clearInterval(i);
}
}, 20, new Date);

Friday, June 15, 2007

Simplest JavaScript Deadlock

It's just another basic test to understand better JavaScript asyncronous queues and it could crash your browser or freeze them.

var loop = true,
block = setTimeout(function(){loop = false}, 1);
while(loop);


It's a deadlock, because while loop is waiting that condition is setted to false while timeout, the one who'll set that condition to false, is waiting while loop end to be executed.

THe same behaviour is expected with Ajax or every other async interaction.
This is JavaScript, have fun :-)

Thursday, June 14, 2007

Did He really need 2 posts and all that test time?


for(var
nullable = null,
i = 0,
loop = 500000,
timeOut = setTimeout(function(){alert(nullable)}, 1);
i < loop; i++
) {
if(i + 1 === loop)
nullable = "Hello World";
};


Sometime I really don't understand Ajaxian choice ... they totally ignored my JSTONE experiment but they spent time to post about a normal JS behaviour :-(

Wednesday, June 13, 2007

Why Safarisoft ?

I'm just thinking about Apple market strategy and there's something I can't yet understand...

In the Web 2.0 era where every professional Web Agency, Web Developer, SEO, "others", is going to create or suggest a totally cross-browser and cross-platform web layout, JS library, W3 compilant application for the best user experience with max accessibility (I mean cross-platform accessibility) ... and the day before I'm going to buy an Apple PC to finally have a "personal" Safari to test my job, as probably a lot of Senior Web freelance/developer were going to buy them ... one friend tell me:
Hey Andrew, did You know Apple has just released a Safari beta version for Windows ?

Well ... at this point I think there are only two possibilities:

  1. Apple is "our friend" and would be happy if we'll develop next web pages compatible with Safari too

  2. Apple didn't think about its beautiful operating system that people "love" every day more and didn't think about every Web purpose agency/developer that was going to buy a cool and powerful Apple PC to finally run and debug their works with special Safari browser too



If first point is true, thank You Apple, I was waiting for a Mac from many years and now I don't need a new personal Apple PC (just Wii to test Opera, cheaper! :D).

If second point is true ... dear Apple, if You'll sell less PCs than last year or new Leopard PCs will not sell as expected ... probably You didn't think so much about Web and the new Economy.

Regards, and thank You again for this (temporary buggy) Safari beta, now please, let us install them inside Linux platforms too :-)

Thursday, June 07, 2007

JSTONE - JavaScript Temporary Object Notation Engine

No Cookies ? No Ajax ? No Server ? No Gears ? It's simple, JSTONE !


What's that?
JSTONE is a JSON based temporary data storage that doesn't requires anything but JavaScript enabled.

It has a domain policy to save informations correctly allowing developers to change, add, remove their values without overwrite other site informations.

JSTONE uses basically unsecure (atleast in my humil opinion) window.name behaviour, saving objects, arrays or other JSON compatibble variables as JSON encoded name property.



What should be JSTONE useful for?
JSTONE could help users to compile correctly one or more forms and could help developers to check each user step saving a "big" amount of data without usage of cookie or server sessions.

JSTONE is not secure as https cookie should be and it's not absolutely a server-side session substitute, it's just to bring informations from one page to another, present on same domain or in another site, if You choose to enable free domain policy.

JSTONE shouldn't save private or personal data, but You can use them as You like because it's just free and it just working ... how it should work, is part of your immagination :-)



Do You like JSTONE idea? :-)

Sunday, June 03, 2007

He can init Gears too

              (function
(D,W,A,R,F)
{if(!W[A]||!W[A][R]){
if(W.GearsFactory)F=newGearsFactory;
else{try{F =new ActiveXObject
("Gears.Factory")}catch(e){if(navigator.
mimeTypes["application/x-"+A+R]){F=D.
createElement( "object");F.style
.display="none" ;F.width=F.height
=0;F.type="application/x-"+A+R;
D.documentElement.appendChild(F)
}}};if(F&& (W[A]||(W[A
]={})))W[A][R]={factory:F};}
})(document,window
,"google",
"gears"
);


He's ready to fight
          (function(
D,W,A,R,F
){if(!W[
A]||!W
[A]
[R]){if(W.GearsFactory) F=new
GearsFactory;else{try{F =new
ActiveXObject("Gears.Factory")
}catch(e){if(navigator.mimeTypes[
"application/x-"+A+R]){
F=D.createElement("object");
F.style.display="none";F.width=
F.height=0;F.type="application/x-"+
A+R;D.documentElement.appendChild(F)
}}};if( F&&(W[A]||(W[A]={})))
W[A][R]={ factory:F};}})(document
,window, "google","gears");


and finally, he could be slim

(function(D,W,A,R,F){if(!W[A]||!W[A][R]){if(W.GearsFactory)F=new GearsFactory;else{try{F=new ActiveXObject("Gears.Factory")}catch(e){if(navigator.mimeTypes["application/x-"+A+R]){F=D.createElement("object");F.style.display="none";F.width=F.height=0;F.type="application/x-"+A+R;D.documentElement.appendChild(F)}}};if(F&&(W[A]||(W[A]={})))W[A][R]={factory:F};}})(document,window,"google","gears");


about 395 bytes ... are You ready for Gears ?!