Proper event binding

Simple test to determine whether the function returned from bind is rereferenceable, such that it can be added and removed as an event listener.

by Lars Rönnbäck

HTML

<body>
    <!-- to be importantly populated elsewhere -->
</body>

CSS

.callout {
    border: 1px solid black;
    padding: 4px;
    margin-bottom: 2px;
}

JavaScript

/*
    Testing that the function returned from bind is rereferenceable, 
    such that it can be added and removed as an event listener.
*/
function MyImportantCalloutToYou(message, otherMessage) {
    this.message = message;
    this.otherMessage = otherMessage;
    this.original = true;
    // the following is necessary as calling bind again does not return the same function
    // so we replace the original function with the one bound to this instance
    this.swap = this.swap.bind(this); 
    this.element = document.createElement('div');
    this.element.setAttribute('class', 'callout');
    this.element.addEventListener('click', this.swap, false);
    this.element.appendChild(document.createTextNode(message));
    document.body.appendChild(this.element);
}
MyImportantCalloutToYou.prototype = {
    message: null,
    otherMessage: null,
    original: true,
    element: null,
    swap: function() {
        this.element.firstChild.nodeValue = this.original ? this.otherMessage : this.message;
        this.original = !this.original;
        // now this function can be properly removed as an event listener
        this.element.removeEventListener('click', this.swap, false);           
    }
}
var callout1 = new MyImportantCalloutToYou(
    'Swapping of messages should only be possible once.', 
    'This is the swapped out message in the first callout.'
);
var callout2 = new MyImportantCalloutToYou(
    'Swapping of messages should only be possible once.', 
    'This is the swapped out message in the second callout.'
);