2

I'm new to JavaScript still, I would say, so I think that the ways I work on projects now are kind of shaping my way of thinking about how things should be done in js. I have understood that one should work preferably with modules when programming in js. This has led me to think about events in js. For example say I have this object Monkey:

function Monkey(color, position){
   this.color = color;
   this.position = position;
   this.jumpAround = function() {
      /* jumps around and screams */
   };
}

And say I have built a whole app like this, with monkeys, giraffes and shih tzus, that interact in a webapp. How should the events then be handled? Are you left to just implement callbackfunctions in a global namespace? Like:

//objects
var monkey = new Monkey(brown, pos);
var giraffe = new Giraffe(yellow, pos);
var shih_tzu = new Shih_tzu(white, pos);

//event handlers
this_and_that.onclick = function() { /* this and that happens */ }
...

And then include this file in the html header? Maybe this is a silly question with an obvious answer, but still too me it seems as if there aren't any good best practices.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
patriques
  • 5,057
  • 8
  • 38
  • 48
  • Perhaps this should help you [What does it mean global namespace would be polluted?](http://stackoverflow.com/questions/8862665/what-does-it-mean-global-namespace-would-be-polluted) – woofmeow Aug 05 '13 at 15:36
  • @Stano I have edited the title once more, I think this reflects the true nature of my question more.. – patriques Aug 05 '13 at 15:44
  • @patriques Shouldn't it be `function Monkey` instead of `var Monkey`? – Oriol Aug 05 '13 at 15:45
  • @Oriol yes it should! – patriques Aug 05 '13 at 15:46
  • A good resource on the topic I found now is: https://github.com/stevekwan/best-practices/blob/master/javascript/best-practices.md – patriques Aug 05 '13 at 15:51

3 Answers3

1

Not entirely sure I understand the question, but if you mean handling the overwriting of events in javascript caused by repeat elem.onclick = function() {} I use this function:

function addEvent(obj,event,func)
{
    if(typeof func !== 'function')
    {
        return false;
    }
    if(typeof obj.addEventListener == 'function' || typeof obj.addEventListener == 'object')
    {
        return obj.addEventListener(event.replace(/^on/,''), func, false);
    }
    else if(typeof obj.attachEvent == 'function' || typeof obj.attachEvent == 'object')
    {
        return obj.attachEvent(event,func);
    }
}
addEvent(this_and_that,'onclick',function(e) {
    //do stuff
});
MDEV
  • 10,730
  • 2
  • 33
  • 49
  • So would you say that this is a best practice for working with eventhandlers in javascript? Or just a way not to clutter the global namespace? – patriques Aug 05 '13 at 15:45
1

You can put all your code within anonymous self-invoking function, this will also create closure:

(function(){
    // create all your objects and define all events handlers here
})();

Then your code will not pollute global namespace and will be inaccessible from outside. All your event handlers will be executed within the closure.

(One side note: you can find this also in jQuery library. At the very end of the script file is the jQuery object exposed to outer world: window.jQuery = window.$ = jQuery;)

Community
  • 1
  • 1
Stano
  • 8,749
  • 6
  • 30
  • 44
1

Here's a fleshed out example for you with object inheritance. http://jsfiddle.net/H4jqF/

CSS - just a base animal object, with a .5 second smooth transition, for when properties change (for example to make our animal JUMP).

.animal {
    position: absolute;
    transition: all 0.5s ease;
    -webkit-transition: all 0.5s ease;
    -moz-transition: all 0.5s ease;
}

JavaScript

// simple HTML animal - parent class
function Animal(color, position) {
    this.color = color;
    this.position = position;
    this.elm = document.createElement("IMG");
    this.elm.className = "animal";
    this.elm.style.backgroundColor = this.color;
    this.update = function() {
        // update the the HTML element
        this.elm.style.left = this.position.x + "px";
        this.elm.style.top = this.position.y + "px";
    };
    this.jump = function(height) {
        // cheesy jump animation
        // we'll use a CSS transition to smooth it out
        this.position.y -= height;
        this.update();
        // hard code it to come back down in 500ms
        // .bind(this) is used to scope the function to this instance
        window.setTimeout(function() { 
            this.position.y += height; 
            this.update(); 
        }.bind(this), 500);
    };
    this.update();
}
// our subclass Dog
function Dog(color, position) {
    // inherit all of the parent objects properties and methods
    Animal.apply(this, arguments);
    // finish setup of the element
    this.elm.src = "dog.png";
    document.body.appendChild(this.elm);
    // add our onclick event that will fire jump
    this.elm.onclick = function() {
        this.jump(100);
    }.bind(this);
}
// spawn some dogs
new Dog("red", {x: 50, y: 200});
new Dog("blue", {x: 200, y: 200});
Louis Ricci
  • 20,804
  • 5
  • 48
  • 62