2012-03-05 13 views
22

que estoy tratando de hacer un proyecto tictactoe en jQuery y estoy teniendo un problema importante ...

Las baldosas están en <td> etiquetas y estoy tratando de haga que cuando el usuario haga clic en el mosaico, invoque la función "marcada".

Si ahora nos fijamos en la función "marcada", $(this) es el nodo <td> desde el que se llamó a la función.

Sin embargo, no estaba haciendo nada, así que revisé la consola y aparentemente $(this) contenía el objeto Ventana DOM.

¿De todos modos puedo enviar el tipo correcto de $(this) a la función "marcada"?

¡Gracias!

<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

¿Quieres pasar en toda la matriz (es decir, 'listCells') o simplemente la celda de tabla que ha hecho clic? - Si tan solo la td en la que hizo clic pudiera usar '$ (" td "). Haga clic en (función() {marcado ($ (esto))});' en su evento de clic ... – Greg

Respuesta

21

Su código no sigue los principios correctos.

$(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. envolver todo en la función document.ready. Evite las variables globales siempre que sea posible.
  2. Aproveche el hecho de que jQuery maneja this para usted. this siempre será lo que esperas si pasas las funciones de devolución de llamada directamente en lugar de llamarlas tú mismo.
+1

Esta es solo una pregunta secundaria, pero tenía curiosidad de saber por qué envolver todo en la función de listo y evitar las variables globales son buenos hábitos de codificación. – wayfare

+0

Además, estoy tratando de crear una matriz de etiquetas "td" presentes. Desde mi entendimiento, la operación de selector $ ("td") devuelve nodeList, no array. ¿Asignar $ ("td") a un objeto jquery $ listCells convierte la lista de nodos en una matriz? – wayfare

+2

@wayfare ** a) ** La contaminación del espacio de nombre global tiene efectos secundarios, la mayoría de las veces las variables de diferentes partes de un proyecto que se sobrescriben entre sí. Mientras un proyecto sea pequeño, esto no sucederá. Cuando un proyecto crece, esto puede presentar errores molestos y difíciles de encontrar. Aparte de eso, es un mal estilo para transportar el estado a través de variables globales. ** b) ** Un objeto jQuery * es * una matriz. No es necesario convertirlo. '$ ('td')' devuelve una matriz de '' nodos. Tenga en cuenta que utilizo '$ varname' para denotar una variable que contiene un objeto jQuery; es una convención. – Tomalak

0

probar esto:

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



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

Enviar el elemento que desencadena el evento a la función de esa manera:

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

y en la función:

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

Usted puede usar el método call para especificar el alcance de la función:

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

Ahora la función marked puede acceder al elemento hecho clic usando la palabra clave this.

+0

Está usando una combinación de '$ (esto) 'y' this' dentro de su función :) – Sarfraz

0

lo necesario para pasar $(this) a su función:

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

y modificar su función como esta:

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

Probar:

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

continuación:

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

Más simplemente, el uso aprieto:

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

OMG, impresionante, super duper, muchas gracias :) –