Reputation: 12186
Let's say I have a class laid out like so:
function slider() {
this.init = function(options, title, content) {
var self = this;
$('body').append('<button type="button">' + title + '</button>')
},
this.create = function(title, content, options) {
var self = this;
self.init(options, title, content);
},
this.closeSlider = function(elem) {
var self = this;
self.assignPositions();
},
this.assignPositions = function() {
alert('assign positions called from button?');
}
}
To create the 'slider', I use this:
var slider = new slider();
Then I call the create function:
slider.create('title', 'content');
My question is, how can I bind the closeSlider function to the button, but it's only linked to the instance that created it? If that makes sense?
Basically, I'll have many buttons with the 'closeSlider' function, and I don't want them all to fire at once, I only want it linked to the instance that created it.
This is also a VERY trimmed down version of my class, just trying to figure this little problem out :)
Cheers
Upvotes: 3
Views: 100
Reputation: 173642
First of all, you should add methods onto the prototype rather than on each instance (saves memory).
Secondly, you can use jQuery's .proxy()
to create an anonymous function that will "hardwire" this to a particular value when it calls your method.
// empty constructor
function slider()
{
}
// define prototype
$.extend(slider.prototype, {
init: function(options, title, content) {
$('<button>', { text: title })
.on('click', $.proxy(this, 'closeSlider'))
.appendTo('body');
},
create: function(title, content, options) {
this.init(options, title, content);
},
closeSlider: function(event) {
// event.target is the HTML element
this.assignPositions(event.target);
},
assignPositions: function(elem) {
alert('assign positions called from button?');
}
});
Upvotes: 0
Reputation: 42746
Use bind on the callback function when setting the event callback
this.init = function(options, title, content) {
var btn = $('<button type="button">' + title + '</button>');
btn.click(this.closeSlider.bind(this));
$('body').append(btn)
},
This will make it so when the closeSlider
function is called it retains the context of the slider
instance that made it. But note this
will no longer be the context of the html element that triggered the event. So you would need to get the target from event.target
There might be another way of doing this without losing the context of the html element i will have to look and re-edit.
Using event.target
this.init = function(options, title, content) {
var btn = $('<button type="button">' + title + '</button>');
btn.click(this.closeSlider.bind(this));
$('body').append(btn)
},
this.closeSlider:function(event){
//`this` will refer to slider instance
//and event.target will be the button dom object
var element = event.target;
});
Passing the button object as an argument in bind
this.init = function(options, title, content) {
var btn = $('<button type="button">' + title + '</button>');
btn.click(this.closeSlider.bind(this,btn));
$('body').append(btn)
},
this.closeSlider:function(btn,event){
//`this` will refer to slider instance
//btn will refer to the jQuery wrapped button dom object
//event.target will still refer to the button dom object
});
Upvotes: 2
Reputation: 1089
Instead of simply appending a string to the body, create a live element with document.createElement
and attach the onclick event before releasing it into the wild.
Here's an example:
function slider() {
this.init = function(options, title, content) {
var myButton = document.createElement("button");
myButton.setAttribute("type", "button");
myButton.innerHTML = title;
myButton.onclick = this.closeSlider;
$('body').append(myButton);
},
//Other object definitions
}
Upvotes: 0