简体   繁体   中英

jQuery: Check if element has a Class, then execute function

I am learning Javascript for the first time. I am making a tic-tac-toe game. This is probably not the best way to code it, but I decided to use the following strategy:

Each of the grids in # is its own div. If a div is occupied by "X", it gets a new class added to it "xClass"; likewise, if it's occupied by "O", its new class is "oClass".

I want to write a function called winCheck() that checks to see if any of the winning combos in the game have had their classes changed to either all X or all O. I have already given the divs their own variables in jQuery.

var winningCombos = [
    [box1, box2, box3], 
    [box4, box5, box6], 
    [box7, box8, box9],
    [box1, box4, box7],
    [box2, box5, box8],
    [box3, box6, box9],
    [box1, box5, box9],
    [box3, box5, box7]
];

so for example, if box1, box2, and box3 are all occupied by X, their class changes to "xClass" and X wins. What function can I use to verify that their class has changed?

I've tried the following:

if (winningCombos[i].children().className === "xClass") {
    alert("Player 1 has won!");

I was also trying the .hasClass() method, could that work?

if (winningCombos[i].children.hasClass("xClass") === "true" {
    alert("Player 1 has won!");

Can anyone help?

Another way you could do this is to set each winning combination with a unique class name. So boxes 1, 2, and 3 would have a shared identifier class.

So you would end up with eight identifier classes judging by your two dimensional array.

If the divs are allowed to be 'X', 'O', or neither. Then you can do a iterator through your identifier classes to see if any individual one has triggered a win condition.

 // Giving the identifier 'tttX' as the class name, X being the unique
 // Could make that an array itself. I am going for quick and dirty here
 $(".board div").click(function(e){
     var winningComboArrayLength = 8; // If the board went to 4x4 it would be 16
     var winningConditionLength = 3;
     for(var i = 0; i < winningComboArrayLength; i++){
         if($("div.xClass.ttt" + i.toString()).length == winningConditionLength){
             // X won logic
             alert('X player won!'); 
         }
         else if($("div.oClass.ttt" + i.toString()).length == 3){
             // O won logic
             alert('O player won!');
         }
     }
 });      

Now that I look further at it, you can create the array out of jQuery objects like so.

And then run through that array to check for winning conditions as a different way.

var winningCombos = [];
$(function(){   winningCombos = [
          $('#box1,#box2,#box3'),
          $('#box4,#box5,#box6'),
          $('#box7,#box8,#box9'),
          $('#box1,#box4,#box7'),
          $('#box2,#box5,#box8'),
          $('#box3,#box6,#box9'),
          $('#box1,#box5,#box9'),
          $('#box3,#box5,#box7')
     ];

     $(".board div").click(function(e){
         var winningConditionLength = 3;
         var maxLength = 0;
         for(var i = 0; i < winningCombos.length; i++){
             if(winningCombos[i].filter('.xClass').length == winningConditionLength){
                 // X won logic
                 $('.result').text('X player won!'); 
             }
             else if(winningCombos[i].filter('.oClass').length == winningConditionLength){
                 // O won logic
                 $('.result').text('O player won!');
             }
         }
     });      


});

I see you have nested array inside winningCombos which isn't used that way in your later code, so I expect it to be like this,

var winningCombos = [
    box1, box2, box3, 
    box4, box5, box6, 
    box7, box8, box9,
    box1, box4, box7,
    box2, box5, box8,
    box3, box6, box9,
    box1, box5, box9,
    box3, box5, box7
];

Yes, hasClass() is better. But you are mixing Javascript objects, arrays and jQuery objects. You can use children() only on jQuery objects and className only on Javascript DOM objects.

So, you will have to check each winning strategy in a cycle. If, for example, box1 is the jQuery object wrapping the very first tic-tac-toe div, this should work:

/**
 * Returns true, if a player with a given symbol won, false otherwise
 */
function checkIfWon(symbol) {
    for (var i = 0; i < winningCombos.size(); i++) {
        var hits = 0;
        for (var j = 0; j < 3; j++) {
           if (winningCombos[i][j].hasClass(symbol + "Class")) {
               hits++;
           } else {
               break; // no need to check this combo on
           }
        }
        if (hits === 3) {
            // we got a winning combo!
            return true;
        }
    }
    return false;
}

if (checkIfWon('x')) {
    alert('First player won!');
} else if (checkIfWon('o')) {
    alert('Second player won!');
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM