I created a class called SearchBox to handle search interaction (delayed trigger, search on enter key press, preventing searches while one is active, synchronizing results when a search completes and the text has changed, etc.).
All the class methods are prototype methods, meant to be accessed via this
. In the following code, assume p
is the class's prototype.
p.registerListeners = function () {
$(this.element).on('keypress', this.searchKeyPressed);
};
p.unregisterListeners = function () {
$(this.element).off('keypress', this.searchKeyPressed);
};
That doesn't work, because when the keypress event calls the searchKeyPressed
handler, it doesn't do so in the context of this
. The only solution I can come up with is one that only modern browsers support, which is to bind the callback to this
, which actually creates a new function. Since it creates a new function, I have to cache it in order to remove it later, since I have to pass the same reference to off
that I passed to on
.
Is there a better way to do it than this, or is this ok?
var boundKeyPressed;
p.registerListeners = function () {
boundKeyPressed = this.searchKeyPressed.bind(this);
$(this.element).on('keypress', boundKeyPressed);
};
p.unregisterListeners = function () {
$(this.element).off('keypress', boundKeyPressed);
};
I thought that maybe jQuery.on
would provide a way to do this event binding automatically, but instead it seems like it binds this
to different things depending on how it's called. For example, when using on('eventname',instance.func)
, this
is the "currentTarget" (not necessarily "target" in bubbling terms), whereas when using on('eventname','selector',instance.func)
, this
refers to the element matching the selector. In either case, the func
runs as though it has no relationship with instance
.
.bind
. Also, come ES6,e => this.method(e);
will work, come ES7, it looks like you can havethis::method
. – Changelingthis::method
, butthat::this.method
and::this.method
andthis::anyFuncWhichExpectsThis
(which is what thethis::method
represented, as the binding to its own method, long-form would bethis::this.method`` or shorthanded to
::this.method. Composing function-chains of completely disparate functions, all expecting this, might become as simple as saying
a( )::b( )::c( )` --divs::sort(divClass)::filter(isOnScreen)::slice(0, 10)
using array methods on a nodelist:const { sort, filter, slice } = Array.prototype;
– Changeling