Bazinga!

Planting Trees in JavaScript Aug 25th 2011

Last week I had great pleasure to take part in Creative HTML5/JavaScript workshop led by Seb Lee-Delisle (check him out at http://sebleedelisle.com/, http://creativejs.com/ and @seb_ly).

We spent two days playing with canvas, particles, trees and 3D stuff. I was (well, I am) a total n00b in animation and I was simply amazed what can be achieved with some simple mathematic formulas and trigonometric functions. Sine wave rocks! :)

Cyber Trees

I particularly liked messing around with drawing trees. During the workshops I played with angles and shapes and got things like that:

Cyber Tree version 1Cyber Tree version 2

Cyber Tree version 3Cyber Tree version 4

Cool, huh?

Zen Tree

The things that we’ve been doing later made my brain kind of explode. For most of the time I was sitting there with my mouth wide open, cursing my limited cognitive abilities. Later, when I went through the code I understood much more of it and I’m even more amazed how clever these thing are.

During my flight back home I created animated tree just to see if I can figure out the formulas. There is a lot of randomness in the value of parameters but I like the result though its level of awesomeness is far from Seb’s übercool robo-tree :)

To be honest it’s little too hypnotic and it is very successful in keeping me away from my dissertation.

So below is the preview, and you can see its gracious, resource-eating movements here:

See Zen Tree in action

 

by: Kasia

Don’t work from home, work from cafe! Jul 7th 2011

Lots of people is jealous when I tell them that I can work from home if I want to. They seem to think that staying at home instead of going to the office is a bliss. No way it is!

Working from home sucks.

It’s boring, unproductive and tiring. The only reason I do it sometimes is when I really have to be there during work hours because Mr. Plummer has to come around 1 p.m. (well, can’t say I blame him for wanting to work regular shifts).

What is better than working from home? Working from cafe of course! And here’s why:

  1. You have to crawl out of bed – take a shower, brush your teeth and get some decent clothes on. Believe me it’s healthier for you and your surroundings, especially if you work remotely for longer time.
  2. Your work is more productive – it’s harder to get distracted, when you’re sitting in some public place. At home you have always some laundry to do, kids to play with, tv series to catch up to, fuse to change… It’s kind of stupid to sit in cafe and watch movies. And at home? Well…
  3. You get to meet people – if you are a freelancer you’ve probably already noticed that we tend to transform to a kind of stinky savages (see point 1) when deprived of human companions. In cafe you have to talk to people and exercise social skills (remember that unused muscle shrinks). Even if you’re not such extreme case, you can always meet some cool cafe occupants and just start talking (‘hey, you also working remotely?’)
  4. You can co-work with your friends from other companies – if you need a break from your colleagues and family just tell some people to come to the same place. You’ll be working on your own stuff and you can talk in between. Maybe you just shouldn’t pick someone you haven’t seen for ages.
  5. You get better coffee (and food) – does your office have better coffee machine than good coffee place? Or perhaps you own one? Yep. That’s what I thought.
  6. You discover your city in a new way – think about it – how often do you even see your city during regular weekday? It’s really interesting to observe what is happening in the city when everyone is stuck in the offices.
  7. You support your local community – yes you do! Think about it – the more people choose to sit in the cafe the more probable is you’ll find one to sit in. Simple demand-supply rule.
  8. It’s more fun! – any doubts here? Plus it’s easier to arrange some meeting with friends after work. All you have to do to get there is to close your laptop.

If you are still hesitating or maybe you’re very much eager to try, but you don’t know where you can go I have a little help for you. Together with my friend Przemek (@powczarek) we slightly abused GitHub to create a tiny project gathering work friendly places.

You can access it here: http://kaaes.github.com/work_from_cafe/ or if you prefer to see it directly on GH use this link https://github.com/kaaes/work_from_cafe

So far it only contains cafes in Krakow, but you’re welcome to add new ones if you want and if you do it, maybe we’ll get motivated to replace static files with something more trendy like JSON.

Now go and multiply your money over cup of nice coffee!

Ps. I’m writing this post sitting in a cafe/bar thing at Vienna airport. I couldn’t get to do this while I was at home. See? Told you! ;)

by: Kasia

SSJS. The brave expedition to the other side of the browser. Jul 5th 2011

Three days of JavaScript on server

Last weekend I had a pleasure to take part in yet another great initiative from the guys that brought us DevMeetings – Piotr, David, Adam and Kamil prepared for us – grab your seats – full three days workshop of server side JavaScript!

When I got invitation to this event I was all thrilled and really surprised – here’s me – the ultimate lover of the browser environment with all its unpredictability and uncertainty and here’s server – the dark land of formless mechanisms. But it was also my dear JavaScript and its brave attempts to conquer this so far hostile territory… and some kinky ideas what we could achieve there… I knew I wanted to go.

Tough start – SSJS DevMeeting in June

To be honest my spirits were kind of down after the Krakow DevMeeting that happened to be about the same topic. This was my first encounter with something more than simple Make your server in 10 lines tutorials and things that David prepared for us made me feel like a complete n00b dragged out of the cozy burrow of browser development.

It was the moment that I thought What the hell I’ll be doing on this DevCamp?, especially that by then I already knew that most of the other guys there have strong background of backend programming. I knew I’d learn a lot but I was afraid that my input might be rather insignificant.

But after all it was extremely valuable time! I learned a lot about various aspects of server JS and it let me verify some wild concepts I had. I also think I had something to share after all :) So here’s my big thank you to organizers and all devs I had pleasure to work with – you guys were great!

And also few of my thoughts about this superhot technology.

It’s SSJS not SSjQuery

The fact that you write your code in JS doesn’t mean any JS dev can just start writing servers in that language. First of all – knowledge of vanilla JavaScript is necessary! Forget about frameworks, forget about DOM, it’s just language itself. Fortunately it’s V8, so you can use all ECMA5 goodness. Closures, callbacks, contexts, event loop – if you don’t know these things by heart don’t event start with SSJS, you’ll get frustrated extremely fast.

If you think that Node.js is some magic server side browser that lets you just move your code from client to server you’re wrong. As a frontender I love to see the results of my work displayed as soon as possible. Bare Node doesn’t give you anything like that – you have to either use existing web framework like Express or struggle with asynchronous callbacks to send both static files and dynamic content to browser.

The Node.js jungle

Oh, and don’t count on documentation – even official one is way too vague and incomplete to create even simple web app using only its reference.

Real ride however begins when you try out modules written by community – there is no list of reliable resources, official github page just lists them all, nobody approves stuff added to npm (Node Package Manager) and nobody controls the quality of the code.

Working with these is like taking part in the rodeo – you never know when you’ll hit the ground and how hard the landing will be. I scored an enormous amount of wtfs and other not ladylike words when it turned out that modules we wanted to use don’t work at all, work only under certain condition or work only once per server run (like the xml parser that could parse exactly one xml and then died).

After this short tryout I know I wouldn’t dare to use any of them in any commercial project. They’re just too unstable. If I wanted to do anything in Node I’d write all the modules from scratch.

RingoJS and v8cgi are there as well

Except from Node that has definitely the biggest hype today, there are also other SSJS solutions that one might want to use.

RingoJS is written in Java and it’s based on Rhino engine. We tested it and turned out to be extremely slow! I’m waiting for more detailed analysis of the collected data but it’s results weren’t very optimistic and it’s performance was dramatically worse than others’.

v8cgi however surprised us in a very positive way. It is apparently stable and dev friendly environment that can be used as an Apache module. It was however playing hard to get. Only few of us managed to install and compile it properly. I personally haven’t been working with it but after seeing the results and hearing the opinions I would like to give it a try. I just have to find someone to help me get it up and running on my machine ;)

Both Ringo and v8cgi don’t have the community Node has but I guess it’s actually not a bad thing! You don’t have dozens of modules to choose from but you also don’t have to fight with messy, half baked, ugly code. They also seem more stable and mature than Node but again – I’m waiting for the DevCamp final analysis.

Same goes for the results of other performance tests including NoSQL databases vs MySQL, security findings and other goodies. So stay tuned – working through this amount of information will probably take some time.

And in so called meantime admire how the codebase was growing during those 3 days:

Middle end – my Holy Grail

The overall result of our research was that this whole SSJS buzz is seems to be rather overrated. Technologies tested weren’t faster, more stable or scalable than well known ones like Java or PHP. We could hardly find any use case that would make using JS on server the best possible solution.

I had however my plan to test it as so called middle end – the term used by Kyle Simpson to describe the layer that can take care of shared client-server functionalities like templates or validation and reduce the amount of code and logic duplication.

I managed to talk others into this idea and… we did it! We wrote the web application that could use the same JS code to dynamically generate content in browser or assemble it on server and serve it statically as html. It worked both with Mustache templates and plain appendChild(). And the mode could be switched by simple query parameter.

Also the validation was performed on both sides with the same methods. No code duplication! That was just awesome.

I definitely see very good reasons for such mechanisms, the most basic example being serving static content to old slow browsers (or to modern slow mobile browsers) or the client-server validation of web forms. Our proof of concept was a success and I am eager to go deeper into this topic.

It seems to be a hype, dear Watson

After these last few days my encounters with SSJS and Node in particular make me think that these technologies aren’t such a big deal.

This whole technology is too young and unreliable to take it into the consideration in commercial projects. Authors probably realize that since the current version of Node is 0.4.9., RingoJS is 0.8 and v8cgi is 0.9. Two latter seem to be more stable than Node but have much less resources to use.

But even leaving instability aside – youth has its rights after all – there was nothing else that could convince us to choose it over other web technologies like PHP, Ruby or Java. Tests showed no advantage of speed or any other aspects of performance. Development in Node is hard and requires very good knowledge of asynchronous nature of the language. Ringo and v8cgi are bit more dev friendly. But migrating to JS just because it’s JS… Hm.

Of course we haven’t checked everything, so maybe there is some aspect that makes it a killer – we however haven’t been able to find it.

DISCLAMER: A day after writing that post (July 6th) I discussed the mysterious case of Node with guys from my team and learned few more things about servers, instances, load balancers, threads, Mongrel, i/o, events, kernel, os and other nuances totally exotic for a non-backend person.

The stuff we talked about made me realize, that I still don’t know enough to decide whether servers written in JS can’t be better option in some cases/configurations.

Generally we agreed that it’s hard to find a model use case for Node, something that would make choosing it over other technologies obvious. From the other hand we (ok – they – as I was mainly listening and demanding real life examples ;) talked about possible scenarios when SSJS might be a solution at least not worse than others.

So hereby, I am officially setting my status back to ‘it’s complicated‘. I hope I’ll manage to talk them into performing some environments/configurations tests because I don’t like not knowing things!!!

*humph*

The beauty is near the surface

But there is a huge bright spot here for me. The big winner is in my opinion SSJS as the middle end. The idea of having a JS module on server that can share the logic with browser is too beautiful to be left aside.

My dangerous adventure on the dark side of the http request turned out to be a great experience after all. Thanks to the support of my brave companions I found a promising path to even more kick ass web apps and learned the ways I don’t want to follow.

Verdict? SSJS stays with me but without its supernatural aura of ultimate awesomeness.

by: Kasia

ECMAScript 5 Object methods cheatsheet Jun 26th 2011

As SSJS DevCamp is getting closer I decided to familiarize myself with some ECMA5 goodness that will be useful in discussion about code security and stability (we’re talking about server after all). There’s a bunch of new methods that give us more control over the objects and their properties and since we have full support for it in V8 they’re definitely something to use there (or at least fight about using).

As it seems my fingers have better connection to my brain than my eyes, my reading ended with some notes. And since I believe that sharing is good, here they are:

EDIT: I fixed the bad example with get/set. Thanks to David for pointing that out.

/**
* Object descriptor
**/

var a = {
  prop1 : 14
}

var descriptorObj1 = Object.getOwnPropertyDescriptor(a, 'prop1');

// Property defined in 'regular' way has descriptor that looks like that
descriptorObj1 is {
  value : 14, // object's value
  get : undefined, // getter function, it's undefined by default
  set : undefined, // setter function, it's undefined by default
  writable : true // can value be changed, true by default
  enumerable : true // will it be visible in for..in loop, true by default
  configurable : true // can you change the descriptor, true
}


/**
* Define single property descriptor
**/

Object.defineProperty(a, 'prop2', { // equivalent of a.prop2 = 'abc'
  value : 'abc',
  writable : true,
  enumerable : true,
  configurable : true
});

Object.defineProperty(a, 'prop3', {})

var descriptorObj3 = Object.getOwnPropertyDescriptor(a, 'prop3');

// Property defined with defineProperty() has different defaults
descriptorObj3 is {
  value : undefined,
  get : undefined,
  set : undefined,
  writable : false
  enumerable : false
  configurable : false
}


var obj = { prop1 : 'aaa' }
Object.defineProperty(obj, '_prop2', {
  get : function() { return this.prop1 }, // it's get and/or set XOR writable
  set : function(val) { this.prop1 = val }, // without set value can't be changed
  enumerable : false,
  configurable : false
})

var obj = {}; // better example from David :)
(function(){
  var __test = 42;
  Object.defineProperty(obj, "test", {
    get: function(){ return __test; },
    set: function(x){ __test=x; }
  });
})();

/**
* Define multiple property descriptors
**/

Object.defineProperties(a, {
  prop5 : descriptorObj,
  prop6 : descriptorObj,
  prop7 : descriptorObj
})

/**
* Create object with given prototype
**/

Object.create(proto [, propertiesObject ]);

var obj, oObj;
obj = Object.create(Object.prototype) // equivalent of obj = {}
obj = Object.create(Constructor.prototype) // equivalent of obj = new Contructor()

obj = Object.create(oObj, { prop1 : descriptorObj }) // defaults are the same as in Object.defineProperty()
obj.prop1 // descriptorObj.value

//to specify an ES3 property
obj = Object.create({}, {
  p: {
    value : 42,
    writable : true,
    enumerable : true,
    configurable : true
  }
});

/**
* Get all enumerable properties
**/

Object.keys(obj) // enumerable only, doesn't go into the prototype chain

var arr = ["a", "b", "c"];
Object.keys(arr); // ["0", "1", "2"]

var obj = { 0 : "a", 1 : "b", 2 : "c"};
Object.keys(obj); // ["0", "1", "2"]

var obj = Object.create({}, { prop1 : { value : 42 } });
obj.prop2 = 24;
Object.keys(obj); // ['prop2']

/**
* Get all properties, enumerable or not
**/

Object.getOwnPropertyNames(obj); // enumerable and not, only on the obj, not deeper

var arr = ['a', 'b', 'c'];
Object.getOwnPropertyNames(arr); // ["0", "1", "2", "length"]

var obj = { 0 : "a", 1 : "b", 2 : "c"};
Object.getOwnPropertyNames(obj) // ["0", "1", "2"]

var obj1 = Object.create(obj, { prop1 : { value : 42 } });
obj1.prop2 = 24;

Object.getOwnPropertyNames(obj1) // ['prop2', 'prop1']
Object.keys(obj1) // ['prop2']
for(var i in obj1) {console.log(i)} // 'prop2', '0', '1', '2'

/**
* Get prototype of specified object
**/

Object.getPrototypeOf(obj)

Object.getPrototypeOf({}) // Object
Object.getPrototypeOf('123') // TypeError

/**
* Prevent any extension of the object
**/

Object.preventExtensions(obj);

// prevent adding new properties
// existing properties can be modified
// existing properties can be deleted
// prototypes can be modified

var obj = { 0 : "a", 1 : "b", 2 : "c"};
var obj1 = Object.create(obj, { prop1 : { value : 42 } });

Object.preventExtensions(obj1);

obj1.prop2 = 2 // undefined or TypeError in strict mode
obj1.prop2 // undefined

obj.prop2 = 2 // ok
obj1.prop2 // 2

/**
* Check if object can be extended
**/

Object.isExtensible(obj); // true if preventExtensions(), seal() or freeze() was used,
                          // false otherwise

/**
* Prevent any extensions, deletions and property changes
**/

Object.seal(obj)

// prevent adding new properties
// existing properties descriptors can't be modified
// existing properties values can be modified
// existing properties can't be deleted
// prototypes can be modified

var obj = { prop1 : 'aaa' }
Object.seal(obj)

obj.prop2 = 'bbb' // TypeError
obj.prop1 = 'bbb' // ok, property value changed
delete obj.prop1 // TypeError
Object.defineProperty(obj, { prop1 : { get : function() { retun 'ccc' } } }) // TypeError

/**
* Check if object is sealed
**/

Object.isSealed(obj); // true if can't be extended and
                      // properties aren't deletable or configurable,
                      // false otherwise

/**
* Prevent any changes to the object
**/
 
Object.freeze(obj);

// object is immutable
// prevent adding new properties
// existing properties descriptors can't be modified
// existing properties values can't be modified
// existing properties can't be deleted
// prototypes can be modified

var obj = { prop1 : 'aaa' }
Object.defineProperty(obj, 'prop2', {
  get : function() { return this.prop1 },
  set : function(val) { this.prop1 = val }
})
Object.freeze(obj)

obj.prop3 = 'bbb' // TypeError
obj.prop2 = 'bbb' // undefined - obj1.prop1 is still 'aaa'
obj.prop1 = 'bbb' // TypeError
delete obj.prop2 // TypeError
Object.defineProperty(obj, 'prop1', { get : function() { return 'ccc' } } ) // TypeError

/**
* Check if object is immutable
**/

Object.isFrozen(obj); // true if obj properties can't be deleted, added nor changed
                      // (both descriptor properties and property value)
                      // false otherwise
view raw objects.js This Gist brought to you by GitHub.
by: Kasia

‘this’ dissected May 19th 2011

I know, I know – this topic has been worked through so many times… But I felt kind of provoked to write that post by numerous job interviews I had a pleasure (though it really wasn’t always a pleasure) to take part in. And I was very surprised to find out that the majority of candidates wasn’t able to tell me what is this object in JS.

Honestly, I think it’s kind of embarrassing when you put in your resume ‘advanced JavaScript knowledge’ and only thing you can say about this is ‘when you click on the button, it refers to this button’.

So here it is – how it works. And if you know anyone who’s going to have interview that includes me – use brute force to make him/her read this before we talk.

this – the basics

The main difference with this between JavaScript and other languages like Java or C++ is that in JS it can change. It doesn’t refer to the object in which its usage was declared (though it can) but to the current context in which function was executed.

Very simple example:

var a, b, c, d, e;

a = function(obj) {
  return this;
}


// when you call the function in 'function form' 'this' is window object
  
  a(); // window

// Always! Even if you define and call it inside another function

  (function() {
    var aa = a;
    var bb = aa();
    return bb; // window
  })();


// when you call it as a method of some object 'this' will be that object
  
  b = { a : a };
  b.a(); // b object


// when you use the function as a constructor with 'new' operator new
// object will be created inside, assigned to 'this' and then returned
  
  c = new a(); // object a - instance of the a constructor function


// when you use the function as a callback for some events on DOM element
// it will be the context of the function

  d = document.getElementById('myDiv');
  d.addEventListener('click', a, false); // HTMLDivElement

Watch out for context!

So this object is evaluated when the function is executed, not defined. Since you can do basically everything with the function in JS – pass it as parameter, assign, return, define in another – you have to be careful when using this. Look at this example:

// create Logger constructor with few properties
var Logger = function(id) {
    this.container = document.getElementById(id);
    this.counter = 0;
}

// add functionalities with prototype
Logger.prototype.log = function(msg) {
    this.container.innerHTML = msg ;
    this.counter++;
}

Logger.prototype.getCounter = function() {
    this.log(this.counter);
}

// create new logger object and log few messages
var logger = new Logger('logger');

logger.log('wow');
logger.log('plum');

So far it is working as expected – it logs the messages to container with given id. But let’s assume we want to display the counter and the trigger will be click on some html element:

var el = document.getElementById('showCounterTrigger');
el.onclick = logger.getCounter

Now what happens after clicking on the counter trigger? getCounter method of logger object is fired and this is what we get from Chrome:

Uncaught TypeError: Object #<HTMLDivElement> has no method 'log'

logger.getCounter was called in the context of div element and this was evaluated as that element – not as logger object!

If you want to make it work properly you have to use another wrapper function. This anonymous function will be called in context of HTML element and function inside will have its normal scope which is logger object in this case:

var el = document.getElementById('showCounterTrigger');
el.onclick = function(evt) { logger.getCounter() }

// if you're operating in ECMA5 environment (webkit or gecko)
// you can also use bind() (more about bind below)

el.onclick = logger.getCounter.bind(logger);

// just remember that every event callback has an event object
// passed as a first parameter, so be careful when reusing methods

It can cause problems also when you try to use it other way around (for example to reuse piece of code)

el.onclick = function(evt) {
  this.style.backgroundColor = '#f00';
  this.style.borderBottom = 'solid 2px blue';
}

el2.onclick = function(evt) {
  this.style.backgroundColor = '#ff0';
  this.style.borderBottom = 'dotted 1px green';
}

// refactor to avoid redundancy

function addStyle(bgColor, border) {
  this.style.backgroundColor = bgColor;
  this.style.borderBottom = border;
}

// it WON'T work because function will be called in context of window!
el.onclick = function(evt) {
  addStyle('#f00', 'solid 2px blue')
}

el2.onclick = function(evt) {
  addStyle('#ff0', 'dotted 1px green')
}

// to make it properly you have to either pass
// the HTML element as parameter...
function addStyle(el, bgColor, border) {
  el.style.backgroundColor = bgColor;
  el.style.borderBottom = border;
}

el.onclick = function(evt) {
  addStyle(this, '#f00', 'solid 2px blue')
}

el2.onclick = function(evt) {
  addStyle(this, '#ff0', 'dotted 1px green')
}

// ...or force the context with call/apply
function addStyle(bgColor, border) {
  this.style.backgroundColor = bgColor;
  this.style.borderBottom = border;
}

el.onclick = function(evt) {
  addStyle.call(this, '#f00', 'solid 2px blue');
}

el2.onclick = function(evt) {
  addStyle.call(this, '#ff0', 'dotted 1px green')
}

This leads us to the next part of the topic

.apply() and .call()

The simplest way to avoid confusion with what the hell is this in that very moment is setting it explicitly. And this is what call and apply are for.

They’re both methods of Function object – prototype of all functions so each defined function can use it. Calling this method will force the value of this. The only difference between those two methods is that with call you have to pass all function’s arguments as separate parameters while apply will accept array of arguments.

call()

functionObject.call(thisObj, arg1, arg2);

apply()

functionObject.apply(thisObj,[arg1, arg2]);

So in previous example we can set the context and pass all parameters required by addStyle function:

el.onclick = function(evt) {
  addStyle.call(this, '#f00', 'solid 2px blue');
}

// both will have identical effect

el.onclick = function(evt) {
   addStyle.apply(this, ['#f00', 'solid 2px blue']);
}

More about call and apply on MDC

A bit of ECMA5 bling – .bind() method

As in case of call and apply bind is also method of Function global object. Its arguments are similar to those of call – first one is an object that will be set as this while the rest will be passed as arguments to the function bind is called on. But it works in a different way.

call and apply execute the function right away, bind does only some initial manipulation so when the function is invoked later it has context and initial parameter already set.

During this initial binding bind sets explicitly the context object and allows you to pre-specify some arguments. If you’re familiar with concept of currying in JSbind does exactly the same.

function sum () {
  var s = 0;
  for (var i = 0, len = arguments. length; i < len; i++) {
    s += arguments[i];
  }
  return s;
}

// execute function and
// return 6, context is window
var simpleSum = sum(1, 2, 3)

// preset first argument, 'this' will be null
// don't execute function yet!
var addToOne = sum.bind(null, 1);

// return 8 - 1 will be the first argument
addToOne(3, 4);

// preset two first arguments, 'this' will be null
var addToThree = sum.bind(null, 1, 2);

// return 10
addToThree(3, 4);
view raw bind_ex.js This Gist brought to you by GitHub.

Sad part about bind is that is not cross browser. It was introduced in ECMA5 (JavaScript 1.8.5) which means it won’t work in IE 6 and 7. Parts of ECMA5 can work in IE 8 and Firefox 3 but safe assumption would be that it’ll be accessible in Firefox 4+, Chrome, Opera 11+, IE 9+ and Safari 5+

You can also implement this method by yourself to make it work in older browsers. Just click the link to MDC below.

More about bind() on MDC

that/self workaround

Probably by now you’ve already noticed that this object is not working as someone used to Java or C++ might think. If you need to have something that will work this way you should use very nifty and simple workaround that bases on closure mechanism.

What it’s all about? You define you own local variable in the place you know what is the value of this (conventionally it’s called that or self) assign this to that/self variable and then use it instead of this inside functions. This way you’re always sure that you’re referencing the right object.

As an example let’s create some objects that will bind DOM elements to JS objects and create some DOM interactions and allow us to store more data.

var JSobj = function(id) {
  var that = this;
  var date = new Date();
  
  that.id = 'JSnode_' + id;
  that.element = document.getElementById(id);
  that.createdAt = date.getTime();

  that.element.addEventListener('click', clickCallback, false);

  function clickCallback(evt) {
    // 'this' is an object on which we call the function
    // 'that' is always the reference to prototype object

    // log id of the HTML element
    console.log('HTML id -> ' + this.id);

    // log id we've given to the JS object ('JSnode_HTMLid')
    console.log('JS id -> ' + that.id);

    // log time of creation
    console.log('created at -> ' + that.createdAt);
  }
}

var divEl = new JSobj('cont');
// it will log:
// HTML id -> cont
// JS id -> JSnode_cont
// created at -> 331305814994963

Summary

As this object is problematic I don’t use it very often and if I do I always have the context of function in mind and treat it like something that will be changing depending on the ways I want to use it. With that approach you can turn this atypical nature of this to your advantage.

I’d say that if you write functions that use this object inside, you should always invoke them with call, apply or bind – that’ll give you full control over it. Just remember that bind is a part of ECMA5 which means it’s not cross browser

But if you need access to some parent object in which your method was created I suggest that you always use closure power and that/self variable.

by: Kasia

Never concatenate strings with ‘+’… Really? Apr 6th 2011

It’s quite common belief that using ‘+’ operator to concatenate strings in JS is lame and slow and better solution is to use array buffer and join it at the end.

In search of ultimate performance I compared both solutions and it turned out… that ‘+’ can be in fact a reasonable solution. All depends on how many strings you concatenate and how long they are.

Test cases

I took two test cases:

One long string that is constructed by concatenation in some kind of loop

// with += on string
var str = '';
for(var i = 0; i < 10000; i++) {
  str += 'blah';
}

vs.

// with array buffer
var arr = [];
for(var i = 0; i < 10000; i++) {
  arr.push('blah')
}
var str = arr.join('');

Lots of separate short strings that are constructed in loop

// with + on string
var str;
for(var j = 0; j < 10000; j++) {
 str = 'a' + 'b' + 'c';
 // and do sth with str - probably append it somewhere
}

vs.

// with array and join()
var str;
for(var i = 0; i < 10000; i++) {
  str = ['a', 'b', 'c'].join('');
  // again do sth with str
}

Findings

  1. For single string using array buffer instead of += makes perfect sense – huge performance difference in older browsers and comparable results in newer ones.
  2. Doing join() on multiple arrays for concatenation is not a good idea. It takes way more time than simple +!

Tests results

For single string

// yellowish line
var str = '', a, b, c, d, e, f;
for(var i = 0; i < 10000; i++) {
  a = 23 + i, b = 'blah' + i, c = 3 - i, d = 9 + i, e = i, f = 3*i;
  str += 'some' + a + 'concatenated' + b + 'string' + c + 'in' + d + 'loop' + e + f;
}
 
// blue line
var arr = [], a, b, c, d, e, f;
for(var i = 0; i < 10000; i++) {
  a = 23 + i, b = 'blah' + i, c = 3 - i, d = 9 + i, e = i, f = 3*i;
  arr.push('some' + a + 'concatenated' + b + 'string' + c + 'in' + d + 'loop' + e + f)
}
var str = arr.join('');

Test functions were run 50 times. Vertical axis represents execution time in milliseconds. Horizontal is number of tests.

Oh, and look at the numbers on vertical axes! Isn’t the difference between old and new ones beautiful? :D

Chrome 10


Firefox 3.6


Opera 11


IE 8


IE 7


IE 6

For multiple strings

Test functions were run 100 times. Vertical axis represents execution time in milliseconds. Horizontal is number of tests.

// yellowish line
var str;
for(var j = 0; j < 20000; j++) {
 str = 'a' + 'b' + 'c';
}
 
// blue line
var str;
for(var i = 0; i < 20000; i++) {
  str = ['a', 'b', 'c'].join('');
}

Chrome 10


Firefox 3.6


Opera 11


IE 8


IE 7


IE 6

by: Kasia

DevMeetings – My First Dive into Mobile Apps Development Mar 27th 2011

Yesterday (26th March) I had an opportunity to take part in one of DevMeetings – the workshop for software developers.

This particular edition is dedicated to development of mobile apps in JavaScript and since workshops are free (!) and there are going to be more of them in next few weeks I strongly suggest you take part in it if only you have opportunity. Here’s the link to agenda (sorry, but it’s Polish only) Programowanie aplikacji mobilnych w JavaScript (Programming of Mobile Apps in JavaScript)

The event was extremely cool and I really recommend staying up to date with those guys because they’re planning to do more interesting stuff. Piotr revealed they’re going to do a session on SSJS. Please, sign me up guys! ;)

I must say, I was skeptical when it turned out that organizers decided to move whole 2-day workshops to Saturday and serve everything in one 12-hour session. I had to get up at 6 a.m. to get from Krakow to Gliwice for 9 a.m. and I wasn’t sure if my intellectual capabilities will hold till 9 p.m.

After whole event I’m still not convinced this was the best approach because my brain refused to cooperate around 7.30 p.m., but in fact I expected it to be worse. The lecture-workshop mix caused us not to go to sleep after dinner and pair (or rather group) programming kept us alert for most of the day.

Great piece of knowledge…

David de Rosier who was leading the workshops is truly an experienced professional and very cool guy :) He provided excellent load of solid practical knowledge in absolutely non-boring way. And it wasn’t Google-type information. He presented some language quirks and nuances about performance that can’t be easily found – I thought, I know a reasonable bit about JavaScript but now I definitely know more.

I also liked the part, where he described various problems one can have while developing for mobile (WebKit Mobile in particular). I hope I’ll have a chance to listen to him again.

Thing worth mentioning is that DevMeetings are for developers who have already some experience, but you don’t have to be proficient in JS to make good use of provided material.

…and tanks making!

Group 7 tank :)

Glide, little one, glide!

But theory is only a theory and main task during the workshop was to create a game – a multiplayer online shooter for Android. With tanks! (I kind of hoped for dinosaurs but tanks are also cool)

Our 60×60px gif angel of destruction used phone’s accelerometer to turn, speed up and slow down and touch events allowed us to open the fire and spread chaos and fear. The ability to drift and dance wasn’t initially our intention but I perceive it as a valuable skill on the battlefield (or during city cruising).

We worked mainly with PhoneGap and we used WebSockets on a node.js server to go online and play with others. Also some jQuery Mobile came up and even Java appeared during adding menu to our app. Well, It seems that I have to learn that language after all… Bleh ;P

<!— Isn’t that amazing, how much hype I’ve managed to put into last paragraph? —>

Another nice thing presented by David was the idea of event-driven applications. It really got to me and I’m already thinking how to implement it in my project at work :)

Generally I had more fun than I expected, I also learned quite a lot of new stuff. It even made me add new category to this blog – “mobile” which I hope to fill. And I’m definitely adding next editions of DevMeetings to my calendar :)

So, again – thank you guys, it was truly great job! Can’t wait for more.

PS. And in the meantime I’m going to have a presentation about HTML5 on Krakspot Tech – this Wednesday (30th March) at 6 p.m. so come over if you’re interested with any of the topics. Or pizza ;)

by: Kasia

Event Delegation – smarter way to handle your events Mar 27th 2011

Ok, I know it’s really discovering the America, but I see surprisingly little event delegation in code that I’m working with. Too little in fact. So I decided to do some nagging about it.

As my dear Really-Big-App is growing and has more and more features, it’s already at the point when overhead from JavaScript processing is clearly visible and performance issues moved up on the priority list. We changed quite a lot of things to speed it up and one of the methods I tried was switching from traditional event handlers to a bit trickier event delegation. I used it on the page with huuuge JS-generated table (YUI DataTable) with hundreds of rows and interactions bound to most of the cells (and yes, I heard about pagination ;) And this caused over 10% improvement in rendering time.

I’ve also came across nice article by Chris Heilmann, which explains what’s this approach is about and how to use it in YUI 2: Event Delegation versus Event Handling

Some basics before we get to the point:

JS Events anatomy – bubbling and capturing

When you interact somehow with the HTML page elements you usually do it on few DOM nodes at the same time. For example, if you have markup like this:

<body>
  <div id="myCont">
    <p><a id="myLink" href="some.html">Some link</a></p>
  <div>
</body>

and you click on the link, you’re also clicking on <p>, <div> and <body> elements. The question is what element gets “clicked” first. If the flow starts from the most inner element and it travels up to its ancestors event is bubbling. All handlers bound to the elements that are on its way (<p>, <div> or <body>) are dispatched in this order. If the direction is opposite we are dealing with capturing.

So this is how it works:

<a> gets clicked

Bubbling: <a><p><div><body>

Capturing: <body><div><p><a>

When you use old way of binding events by someHTMLnode.onclick browsers dispatch event in bubbling order. If you use addEventListener method you can specify if you want to use capture or bubbling phase:

interface EventTarget {
  void addEventListener(in DOMString type,
                         in EventListener listener,
                         in boolean useCapture);
};

var link = document.getElementById('#myLink');

// use bubbling:
link.addEventListener('click', callbackFnForClick, false);

// use capturing
link.addEventListener('click', callbackFnForClick, true);

Good article about browsers’ behavior when it comes to propagation of events was written some time ago by PPK: Event order

Much more detailed information on DOM Events can be found here Document Object Model Events [W3C]

Actual event delegation with capturing

Why is this relevant to the topic? Basically, event capturing means that you can bind event listener to parent object and it will be fired by interaction with its descendants.

Callbacks of the events have access to Event object which contains information about the dispatched event. Among many others it has two very useful properties – Event.target and Event.currentTarget:

function callbacFnForClick(evt) {
  alert(evt.target) // the element that the event is fired on
  alert(evt.currentTarget) // the element that the event was bound to
}

var myCont = document.getElementById('myCont');

myCont.addEventListener('click', callbackFnForClick, false)

So when you click on <a> element it bubbles up to <div> where callbackFnForClick is fired (and later event goes to <body>). Inside callbackFnForClick evt.target will be the reference to <a> element, while evt.currentTarget is <div> element that we attached event to. Then you can add some logic to the callback function that will recognize which element is being clicked and will perform some actions if this was a link:

function callbackFnForClick(evt) {
  // this is of course veeery naive and any framework method designed
  // for delegation will just use your callback on correct object
  // and in correct context in much smarter way
  
  if(evt.target.nodeName.toLowerCase() === 'a') {
    // do some interactions
  }
}

(IE of course has to do this differently and it keeps clicked object inside event.srcElement instead of event.target)

Why delegation is better?

Now, the benefits of delegation can be not obvious yet, but take this code:

<body>
  <div id="myCont">
    <p><a id="myLink1" href="some.html">Some link 1</a></p>
    <p><a id="myLink2" href="some.html">Some link 2</a></p>
    <p><a id="myLink3" href="some.html">Some link 3</a></p>
    <p><a id="myLink4" href="some.html">Some link 4</a></p>
    <p>...</p>
    <p><a id="myLink57" href="some.html">Some link 57</a></p>
  <div>
</body>

Normally when you’d like to attach some listeners to all links inside container you’d have to get all of them, iterate through the collection and add function to each element:

var container = document.getElementById('myCont');
var links = container.getElementsByTagName('a')
 
// gazillion of links on the page
for(var i = 0, length = links.length; i < length; i++) {
  links[i].addEventListener('click', clickCallbackFn, false);
}

With delegation, you have to add only one listener and you have to do it only once:

var container = document.getElementById('myCont');
 
container.addEventListener('click', clickCallbackFn, false);
// or
delegate('click', container, 'a', clickCallbackFn);
 
// where delegate can look like this
function delegate(eventType, elementToBind, delegateTo, callbackFn) {
  // modern browser
  if (elementToBind.addEventListener){
    elementToBind.addEventListener(eventType, function(evt){
      // again this is very primitive and lets you
      // to operate only on tag selectors
      if(evt.target.nodeName.toLowerCase() === delegateTo.toLowerCase()) {
        // call callbackFn in context of evt.target with proper arguments
        callbackFn.call(evt.target, evt);
      }
    }, false);
  
  // IE
  } else if(elementToBind.attachEvent) {
    elementToBind.attachEvent('on' + eventType, function(evt){
      if(evt.srcElement.nodeName.toLowerCase() === delegateTo.toLowerCase()) {
        callbackFn.call(evt.srcElement, evt);
       }
     });
   }
 }

It’s so cool because:

  1. You have less looping and DOM operations which saves you some time.
  2. Usually with delegation you get less code to maintain
  3. No need to create dozens of references to callbacks
  4. When you add listener to parent element you can dynamically modify its content and handler will still work correctly. If you do it traditionally, you have to attach new listeners each time you add new link, which can be annoying and adds lines to you code
  5. Delegation is a nice pattern that allows you to handle sections of your pages/apps – you can intercept events that happen on containers like navbar or footer and then distribute them further. This might be useful when writing mashups or other modular apps.

Frameworks’ support for event delegation

This pattern is actually nothing new – it is implemented in all frameworks I checked (YUI, jQuery, ExtJs, Prototype.. etc). Example comes from YUI:

Y.Node.delegate() method works very similar to simple event listener Y.Node.on(). All important parameters like event object or this work like in traditional handling.

function callbackFn(event) {
  alert(this) // we expect it to be clicked link element
  event.target // <a> in both cases
  event.currentTarget // this is where difference sits
}
 
// add listener for callbackFn to all link elements
Y.on('click', callbackFn, 'a')
 
// add listener to #myCont element and
// delegate callbackFn to all link elements inside
Y.delegate('click', callbackFn, '#myCont', 'a')

The very cool thing about YUI is that they added the same functionality for events like focus and blur that normally do not bubble. Like!

by: Kasia

Quick Tip: Avoid IE Memory Leaks with YUI Jan 20th 2011

Memory leaks in IE 6/7 are quite well known problem, that has been thoroughly explained and mostly fixed by JS frameworks. Nevertheless, I spent last week fighting those nasty little buggers in the Really-Big-App. I managed to get rid of them and it actually turned out to be pretty straightforward. So below you’ll find some tips on how to easily plug the holes.

One quite important part is, that we use YUI, so I can’t say these are valid for other libraries (but I guess any decent framework shoud have such mechanisms).

What they are?

In general memory leaks happen when circular reference is created between DOM and JS objects. IE 6 & 7 have two garbage collectors and when such a circular link is created, the browser is not able to free the memory unless you close the browser (IE6) or tab (IE7).

As I mentioned above, the mechanism of memory leaks has beed already explained in many great articles. If you’re interested, here are some of them:

How to avoid them?

Fortunately, it’s not so easy to create lekas when you use JS frameworks. They’re designed to make our life easier, so they have some nice features implemented. I must say that this week really learned me to have more trust in YUI smartness and cured me from attempts to hack it ;)

Use framework’s way of binding events

YUI has really nice ways of handling DOM events and their callbacks. Basically, each time when you use library’s mechanism to bind events to DOM nodes (with Y.on() or Y.delegate()) they’re registered and when you leave the page (unload event occurs) YUI removes all of  the references, so they don’t cause leak. Generally, the easiest solution is not to try to outsmart the framework and bind anything in a different way (e.g. via attachEvent).

If you have any third-party libraries that don’t belong to the framework, check them as well. We used Modernizr that had events attached via addEventListener/attachEvent and that plus some scope issues was causing a leak. I created a YUI module of it and replaced listeners with Y.on() and it fixed the leak.

Watch out for innerHTML‘s and other DOM manipulation

If you app is built from modules and you manipulate DOM on single page (add or remove elements), you can cause leaks. When you bind some callbacks to DOM objects via Y.on() and then just remove the DOM objects (for example by setting innerHTML to some other chunk of code), the references will be kept and leak memory.

Solution is again deadly simple – use framework functions for that – you should purge the element or detach the event before removing any DOM elements. Another useful methods are Y.Node.remove() and Y.Node.destroy() that also null out any references inside node that is being removed. (YUI Node API).

In general, the key is to make sure that all DOM<->JS references will be removed.

The framework will do it for you, just don’t try to interrupt. But remember that when you add/remove any DOM elements on the page, you should always look for some method that will purge the node you’re just messing with.

AJAX

I don’t know, what you have to do to cause a leak with AJAX calls, when using YUI mechanisms :) If there were no hacks implemented, the AJAX is not likely to loose memory. If any other part of the app uses some custom implementation of XHR I would suggest refactoring it to some trusted solution.

Bonus: YUI lte 3.2 bug

And one tricky part in the end – if your app leaks for no reason, look for code that extends native Function object. In YUI 3.2 and earlier versions there is a bug that causes a leak on window object (or at least this is how it looks like). Any code like this

  Function.prototype.myFun = function() {
        /** whatever you put here, there's going to be a leak **/
  }

will leak no matter what you put inside this function. I guess this has something to do with closure pattern – probably some reference is kept in scope of added method. They fixed it in YUI 3.3 so all you have to do is update the library or, if from some reasons you can’t, just null out added method on unload event:

  Y.on('unload', function(){
    Function.prototype.myFun = null;
  })

Tools

There is no good tool for leak detection (or at least I wasn’t able to find one). However here are some that turned out to be useful:

  • sIEve – worked the best for me. When it showed no leaks, the memory usage in task manager wasn’t increasing. It did when it showed that the app leaked
  • JavaScript Memory Leak Detector (v2) – it works in general but sometimes it shows no leaks when memory is in fact running out
by: Kasia

Quick Tip: bulletproof CSS gradients Dec 25th 2010

CSS gradients are cool, but aren’t supported by all browsers. For ones that don’t have it implemented you have to use background image. The crossbrowser solution is really simple:

#container {
  background: #fff url(gradient.gif) repeat-x bottom;
  background: -webkit-gradient(
    linear, 0 100%, 0 0,
    from(#ecebe7), color-stop(50%, #fff), to(#fff)
  );
  background: -webkit-linear-gradient(bottom, #ecebe7, #fff 50%, #fff);
  background: -moz-linear-gradient(bottom, #ecebe7, #fff 50%, #fff);
}
view raw gradients.css This Gist brought to you by GitHub.

What is important, the browsers that do support CSS gradients will not pull background image from server and will save you one http request :)

The thing you have to watch out for is color-stop part for webkit. It accepts only percentage or values from 0 to 1 – you can’t use pixels there. For Firefox you can use percentage or any other unit.

And of course working demo :)

That one was tested on Firefox 3.6, Chrome 8, Opera 11, IE 6/7/8, Android 2.1

EDIT: As Mariusz noticed some time ago webkit changed it’s approach to gradients syntax and now uses one similar to mozilla.

by: Kasia