Reputation: 13263
Example:
I want to create a multi-window webapp. Each window is a jQuery object (with a DOM element attached to it), but it should also have specific properties and methods (such as close()
or minimize()
). It seems then, that I should create a class MyWindow
with a property DOMElement
which would contain the jQuery object.
But how will I bind DOM events to the MyWindow
objects?
I could do something like MyWindow.DOMElement.on('click', function(){...}
. But the DOMElement
doesn't know which MyWindow
it's attached to and won't be able to manipulate it's properties if needed. For example, it wouldn't be able to invoke it's MyWindow
's close()
method.
I currently see two ways of solving this problem.
First. Extend the jQuery object in MyWindow.DOMElement
property with a single property myWindow
which would point to the object's parent MyWindow
object.
Second. Extend the jQuery object with the MyWindow
's properties and make it an instanceof
MyWindow
as well (through parasitic inheritance, perhaps?). This way event handlers will have access to all properties and methods of MyWindow
through the use of this
.
Both ways seem somewhat weird.
What is the preferred way to assign a DOM object to a Javascript object for event binding?
Upvotes: 1
Views: 108
Reputation: 1734
I would essentially do as you say in your first solution:
MyWindow objects containing the relevant jquery object for the dom element as one of its properties:
var MyWindow = function(params) {
this.close = function() {/*close window*/};
this.minimise = function() {/*minimise window*/};
this.$elm = $('#'+params.id);
// do all the other stuff you have to do to initialise the window
this.$elm.myWindow = this;
}
Then to bind a click:
window1 = new MyWindow({id: 'window'});
window1.$elm.on('click', function() {
this.close();
});
EDIT: An alternative that I recently used is to have a separate event handler that routes events to the correct method of the correct object however this requires you to keep track of which ids correspond to which objects as the following code illustrates:
var myWindows = [];
var MyWindow = function(params) {
// initialise object
myWindows[params.id] = this;
};
$(function() {
$(document).on({
click: function(e) {
var myWindow = myWindows[$(this).attr('id')];
if (typeof myWindow.click === 'function') {
myWindow.click(e);
}
}
}, '.myWindow');
};
You then bind events by simply adding the appropriate method to the object
var myWindow = new MyWindow({'id': window});
myWindow.click = function(event) {
this.close();
};
However, the danger with this approach is that you have to be very careful about keeping the myWindows array up to date or you get all sorts of memory leaks (clearly the difficulty/importance of this will depend on the context of your app).
Upvotes: 1