jQuery onclick without 'this' [duplicate]

223
August 11, 2017, at 04:06 AM

This question already has an answer here:

  • How do I pass the this context into an event handler? 2 answers
// Block class
function Block(id) {
    this.element = $('<td>');
    $(this.element).click( function() {
        console.log(this);
    });
}

The console log outputs the HTML element that is clicked, which is not what I want. I would like to access the Block object associated to this element instead. How is this possible?

Answer 1

you can also use the arrow function, which is newly defined in ES6.

"An arrow function expression has a shorter syntax than a function expression and does not bind its own this, arguments, super, or new.target. Arrow functions are always anonymous. These function expressions are best suited for non-method functions, and they cannot be used as constructors."

function Block(id) {
    this.element = $('<td>');
    $(this.element).click( () => {
        console.log(this); // now this will be what it was outside of the anonymous function passed into .click
    });
}

Note that not all browsers have implemented this functionality. I believe it works in chrome but not IE (of course). So if you want to use this feature I would also suggest that you look at using a javascript transpiler (I would recommend Babel), which will convert your javascript to be compatible with specific browser versions. So after using babel on the above function the javascript will look something like this

function Block(id) {
    var objectReference = this;
    this.element = $('<td>');
    $(this.element).click( function() {
        console.log(objectReference); 
    });
}

You could of course always just write your function like above and not need to use Babel. Babel is really only worth it if you want to ensure browser compatibility or if you plan on using more ES6 features.

Answer 2

An alternative solution to the ones posted is to use bind:

function Block(id) {
    this.element = $('<td>');
    $(this.element).click(console.log.bind(this));
}

This approach is nice as it doesn't require the extra context-saving variable.

Answer 3

You can capture the value of this in a variable outside the click handler:

function Block(id) {
    var self = this; //capture "this" in outside context
    this.element = $('<td>');
    $(this.element).click(function() {
        console.log(self);
    });
}
Answer 4

The function you are passing to the .click() method exists in the context of your element, and so this in that context refers to the element. By saving the outer context in a variable you can access it inside your new context:

// Block class
function Block(id) {
    var self = this;  // here, this refers to Block()
    this.element = $('<td>');
    $(this.element).click( function() {
        console.log(this); // here this refers to element
        console.log(self); // here self refers to Block()
    });
}
Rent Charter Buses Company
READ ALSO
Using click event from external JS file to control Tumult Hype timeline

Using click event from external JS file to control Tumult Hype timeline

I have a hype project that I'm exporting and embedding into a WordPress theme (long story)I have a seperate JS file that is in the WordPress theme and I'm trying to get a click event within the external JS file to stop playback on a specific timeline...

271
vue2 how to access parent index multiple v-for

vue2 how to access parent index multiple v-for

i have a multiple v-for of nested array object, what i'm trying to do is to access to the parent index

351
jQuery callback function executed but not when expected

jQuery callback function executed but not when expected

I have the following function with callbackthe function renders a canvas to div then the callback hides the canvas

347
How to stream simple webpage (HTML/CSS/Javascript) like a video on a smartTV [on hold]

How to stream simple webpage (HTML/CSS/Javascript) like a video on a smartTV [on hold]

I work in a IT company and we have a lot of numbers, data, statistics of our tickets in some databases and we have a some useless smartTV (2015/2016) around the office

297