Wrapping Existing Event Handlers in JavaScript

When working with frameworks, such as Intrexx or IBM Business Process Manager, you often want to extend existing UI controls. You want to prepend or append event handlers to the ones already in place. This post explains how this can be done.

Why not addEventListener?

The obvious solution is simply using addEventListener. However, sometimes you want to do a little more, and need a little more control. Perhaps the event handler that needs to be extended is not a standard event. Or perhaps you need to do something specifically before or after the existing function is called.

Wrapping an existing function

Suppose we have an object obj with a property change(). The trick is to store the original function away and replace it with a new function which calls the original function. The concept looks like this:

// Store original function:
var _change = obj.change;

// Replace with new function:
obj.change = function(){
  // Do something before...
  _change();
  // Do something after...
}

A full example can be seen below. Changing the value of the text field triggers the change funtion. In the JavaScript tab you can see the additional function that “wraps” the original function, i.e. calls the original function.

See the Pen Example 1 by Christian Templin (@cianty) on CodePen.

Fixing this

The above pattern is a bit buggy. Since we “move” the original function into our new function any code which uses the this keyword gets broken. Take a look at the following example: On every change the original functionality calls an alert which prints the text input’s value. By moving the function, this no longer refers to the text input.

See the Pen Example 2: We broke this by Christian Templin (@cianty) on CodePen.

The solution to this is using call or apply. When executing the function via call/apply you can explicitly provide the this context, so that the original functionality is kept intact.

See the Pen Example 3: Fixed this by Christian Templin (@cianty) on CodePen.

Conclusion

The following pattern can be used to prepend or append code to an existing JavaScript function. Whether to use call or apply depends on how you want (need) to pass your arguments.

// Store original function:
var _change = obj.change;

// Replace with new function:
obj.change = function(){
  // Do something before...
  _change.call(this);
  // Do something after...
}