2012-03-05 13 views
22

Sto cercando di fare un progetto tictactoe in jQuery e sto avendo un grosso problema ...

Le piastrelle sono in <td> tag e sto cercando di fallo in modo che quando l'utente fa clic sul riquadro, chiami la funzione "contrassegnata".

Se esaminiamo la funzione "contrassegnata", $(this) è il nodo <td> da cui è stata chiamata la funzione.

Tuttavia, non stava facendo nulla quindi ho controllato la console e apparentemente $(this) conteneva l'oggetto Finestra DOM.

Esiste comunque la possibilità di inviare il tipo corretto di $(this) alla funzione "contrassegnata"?

Grazie!

<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"); 
    } 
+0

Vuoi passare l'intero array (vale a dire 'listCells') o solo la cella di tabella si è fatto clic su? - Se solo il td su cui hai cliccato potresti usare '$ (" td "). Click (function() {marked ($ (this))});' nel tuo evento click .. – Greg

risposta

21

Il codice non segue i giusti principi.

$(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. Avvolgere tutto nella funzione document.ready. Evita le variabili globali laddove possibile.
  2. Fare uso del fatto che jQuery gestisce this per voi. this sarà sempre quello che ti aspetti se passi direttamente le funzioni di callback invece di chiamarle tu stesso.
+1

Questa è solo una domanda a parte, ma ero solo curioso di sapere come avvolgere tutto nella funzione ready ed evitare variabili globali sono buone abitudini di codifica. – wayfare

+0

Inoltre, sto provando a creare una serie di tag "td" presenti. Da quanto ho capito, l'operazione di selezione $ ("td") restituisce nodeList, non array. Assegnando $ ("td") a un oggetto jquery $ listCells convertirà il nodelist in un array? – wayfare

+2

@wayfare ** a) ** L'inquinamento del namespace globale ha effetti collaterali, le variabili più importanti da parti diverse di un progetto che si sovrascrivono a vicenda. Finché un progetto è piccolo, questo non succede. Quando un progetto cresce, questo può introdurre bug fastidiosi e difficili da trovare. A parte questo, è uno stile cattivo trasportare lo stato attraverso variabili globali. ** b) ** Un oggetto jQuery * è * un array. Non c'è bisogno di convertirlo. '$ ('td')' restituisce una matrice di '' nodi. Nota che uso '$ varname' per indicare una variabile che contiene un oggetto jQuery - è una convenzione. – Tomalak

0

provare questo:

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



function marked(o,arr) 
{ 
... 
9

Invia l'elemento che genera l'evento alla funzione così:

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

e nella funzione:

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

È possibile utilizzare il metodo call su specificare la portata per la funzione:

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

Ora la funzione marked può accedere all'elemento cliccato utilizzando la parola chiave this.

+0

Sta usando mix di '$ (this) 'e' this' all'interno della sua funzione :) – Sarfraz

0

è necessario passare $(this) alla funzione:

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

e modificare la funzione in questo modo:

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"); 
} 
0

Prova:

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

Poi:

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"); 
} 
0
$(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; 
     } 
    } 
}); 
4

Più semplicemente, l'uso si legano:

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

OMG, Fantastico, super duper, grazie mille :) –

Problemi correlati