How to pass $(this) properly in click jQuery function

I am trying to make a tictactoe project in jQuery and I am having a major problem...

The tiles are in <td> tags and I am trying to make it so that when the user clicks the the tile, it calls the "marked" function.

If we now look into the "marked" function, $(this) is intended to be the <td> node that the function was called from.

However, it wasn't doing anything so I checked the console and apparently $(this) was containing the DOM Window object.

Is there anyway I can send the right kind of $(this) to the "marked" function?

Thank you!

<script type="text/javascript"> var TURN_X = false; var TURN_O = true; var turn = false; // this is to see whos turn it is. $(document).ready(function(){ var listCells = $.makeArray($("td")); $("td").click(function(){marked(listCells)}); //THIS IS WHERE I HAVE PROBLEMS return false; }); function marked(arr) { console.log($(this)); // THIS CONSOLE LOG RETURNS "DOM Window" $(this).addClass("marked"); if(turn == TURN_X) { this.innerHTML = "X"; turn = false; } else this.innerHTML = "O"; var tileNum = $(this).attr("id"); } 
1

8 Answers

You code does not follow the right principles.

$(function(){ var TURN_X = "X", TURN_O = "O", turn = TURN_O, $listCells = $("td"); function marked() { // define event handler var $this = $(this), tileNum = $this.attr("id"); if ( !($this.hasClass("marked") ) { $this.addClass("marked").text(turn); turn = (turn == TURN_X) ? TURN_O : TURN_X; } } $listCells.click(marked); // attach event handler }); 
  1. Wrap everything in the document.ready function. Avoid global variables wherever possible.
  2. Make use of the fact that jQuery manages this for you. this will always be what you expect if you pass callback functions directly instead of calling them yourself.
3

Send the element which fire the event to the function like that:

$("td").click(function(){ marked($(this)); return false; }); 

and in the function:

function marked(td) { console.log($(td)); $(td).addClass("marked"); //.... } 

More simply, use bind :

$(".detailsbox").click(function(evt){ test.bind($(this))(); }); function test() { var $this = $(this); } 
0

Try:

$("td").click(function(event){ marked(listCells, $(this)); }); 

Then:

function marked(arr, sel) { console.log($(this)); sel.addClass("marked"); if(turn == TURN_X) { this.innerHTML = "X"; turn = false; } else { this.innerHTML = "O"; } var tileNum = $(this).attr("id"); } 

try this:

$(function(){ var listCells = $.makeArray($("td")); $("td").click(function(){marked($(this),listCells)}); }); function marked(o,arr) { ... 

You can use the call method to specify the scope for the function:

$("td").click(function(){ marked.call(this, listCells); }); 

Now the marked function can access the clicked element using the this keyword.

1

You need to pass $(this) to your function:

$("td").click(function(){ marked(listCells, $(this))} ); 

And modify your function like this:

function marked(arr, that) { that.addClass("marked"); if(turn == TURN_X) { that.innerHTML = "X"; turn = false; } else that.innerHTML = "O"; var tileNum = that.attr("id"); } 
$(document).ready(function(){ var TURN_X = false, TURN_O = true, turn = false, listCells = $.makeArray($("td")); $("td").click(function() { marked(listCells, this) }); function marked(arr, self) { $(self).addClass("marked"); if(turn == TURN_X) { self.innerHTML = "X"; turn = false; }else{ self.innerHTML = "O"; var tileNum = self.id; } } }); 

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like