Shannon Hochkins
Shannon Hochkins

Reputation: 12186

Bind event relative to the class that created it?

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

Answers (3)

Ja͢ck
Ja͢ck

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

Patrick Evans
Patrick Evans

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.

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

Kodlee Yin
Kodlee Yin

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

Related Questions