2012-03-05 6 views
22

tôi đang cố gắng để thực hiện một dự án tictactoe trong jQuery và tôi đang gặp một vấn đề lớn ...

Các gạch đang <td> thẻ và tôi đang cố gắng để làm cho nó để khi người dùng nhấp vào gạch, nó gọi là "đánh dấu" chức năng.

Nếu bây giờ chúng ta nhìn vào chức năng "được đánh dấu", $(this) được dự định là nút <td> mà chức năng được gọi.

Tuy nhiên, nó không làm bất cứ điều gì vì vậy tôi đã kiểm tra giao diện điều khiển và dường như $(this) chứa đối tượng Cửa sổ DOM.

Tôi có thể gửi đúng loại $(this) cho hàm "được đánh dấu" không?

Cảm ơn bạn!

<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

Bạn có muốn vượt qua trong toàn bộ mảng (ví dụ: 'listCells') hay chỉ là ô trong bảng bạn nhấp vào? - Nếu chỉ td bạn nhấp vào bạn có thể sử dụng '$ (" td "). Click (function() {đánh dấu ($ (this))});' trong sự kiện click của bạn .. – Greg

Trả lời

21

Bạn không tuân theo các nguyên tắc đúng.

$(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. Quấn tất cả mọi thứ trong hàm document.ready. Tránh các biến toàn cục bất cứ khi nào có thể.
  2. Sử dụng thực tế là jQuery quản lý this cho bạn. this sẽ luôn là những gì bạn mong đợi nếu bạn chuyển trực tiếp các chức năng gọi lại thay vì tự gọi chúng.
+1

Đây chỉ là một câu hỏi phụ nhưng tôi chỉ tò mò tại sao gói mọi thứ trong hàm sẵn sàng và tránh các biến toàn cầu là thói quen mã hóa tốt. – wayfare

+0

Ngoài ra, tôi đang cố tạo một mảng các thẻ "td". Từ sự hiểu biết của tôi, thao tác chọn $ ("td") trả về nodeList, không phải mảng. Sẽ gán $ ("td") cho một đối tượng jquery $ listCells chuyển đổi nodelist thành một mảng? – wayfare

+2

@wayfare ** a) ** Ô nhiễm không gian tên toàn cầu có các tác dụng phụ, hầu hết các biến nổi bật từ các phần khác nhau của dự án ghi đè lên nhau. Miễn là một dự án nhỏ, điều này không xảy ra. Khi một dự án phát triển, điều này có thể giới thiệu các lỗi khó chịu và khó tìm. Ngoài ra nó là phong cách xấu để vận chuyển nhà nước thông qua các biến toàn cầu. ** b) ** Đối tượng jQuery * là * một mảng. Không cần phải chuyển đổi nó. '$ ('td')' trả về một mảng các nút ''. Lưu ý rằng tôi sử dụng '$ varname' để biểu thị một biến chứa một đối tượng jQuery - đó là một quy ước. – Tomalak

0

thử điều này:

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



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

Gửi các yếu tố mà bắn sự kiện để các chức năng như thế:

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

và trong hàm:

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

Bạn có thể sử dụng phương pháp call để xác định phạm vi cho các chức năng:

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

Bây giờ marked chức năng có thể truy cập vào các yếu tố nhấp bằng cách sử dụng từ khóa this.

+0

Ông đang sử dụng kết hợp của '$ (this) 'và' this' bên trong hàm của mình :) – Sarfraz

0

Bạn cần phải vượt qua $(this) đến chức năng của bạn:

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

Và sửa đổi chức năng của bạn như thế này:

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

Hãy thử:

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

Sau đó:

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

Nhiều cách đơn giản, sử dụng ràng buộc:

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

OMG, Tuyệt vời, siêu duper, cảm ơn rất nhiều :) –