ajb ajb - 1 month ago 7
HTML Question

Why does $(this) work differently depending on how callback is created?

I'm trying to display a table and cause certain actions to take place if the user clicks on a cell in the table. My Javascript (using jquery-3.1.1.min) looks like this:

$(function() {

function tdHeader(key) {
return '<td class="mytable-cell" data-key="' + key + '">';
}

function clickHandler() {
alert("Key: " + $(this).data("key"));
}

function displayTable() {
var tabHTML = '<table class="mmmtab">';
tabHTML += '<tr><th>Data1</th><th>Data2</th><th>Data3</th></tr>';
for (var i = 0; i < 3; i++) {
tabHTML += '<tr>';
for (var j = 0; j < 3; j++) {
key = i + "-" + j;
tabHTML += tdHeader(key) + ((i + 1) * (j + 1)) + '</td>';
}
tabHTML += '</tr>';
}
tabHTML += '</table>';
$("#mytable").html(tabHTML);
$(".mytable-cell").click(clickHandler); // Version 1
// $(".mytable-cell").click(function() {clickHandler();}); // Version 2
}

displayTable();
});


What I'm finding is that if I use Version 1 to set up the callback, then if I click on a cell, the alert box displays the correct key. However, if I use Version 2, the alert box says "Key: undefined".

What's going on, and why does it make a difference which callback I use?

[Assuming I need the Version 2 because I want to pass some local data to the handler, I can solve my problem by passing
$(this).data("key")
as a parameter to the handler. But I'd still like to know why it's doing this.]

Answer

jQuery .on will change 'this' automatically for your event callback. In version 1, 'this' in clickHandler will be $(".mytable-cell"). But in version 2, 'this' is window. (Because your event callback calls clickHandler, clickHandler makes a new context)

please try:

$(".mytable-cell").click(function() {clickHandler.bind(this)();});