-1

This is my code. It's a card memory game that's based around flipping 2 cards and matching them.

First, how can I define the variable $dis in order for it use the $(this) from the scope of the click event function?

var checkMatch = function(){
    if ($clicked.length > 1){
        if ($card1 === $card2){
            $dis.toggleClass('match');
            $matched.push($clicked);
            console.log('MATCH');
            $clicked = [];
            console.log($matched);
            console.log($clicked);
        }else {
            $clicked = [];
            $('.card').removeClass('open show');
            console.log('NOT A MATCH!')
        };
    }else{

    };
};

Here's the full project: https://jsfiddle.net/z1fzfu69/

Another problem I have is that my code finds all of the cards as matches, it is supposed to get 2 cards that I clicked, put them inside an array and compare them. But it just comes out as "MATCH" on all of them.

alexander.polomodov
  • 5,396
  • 14
  • 39
  • 46
Cosmindru
  • 27
  • 8

2 Answers2

0

You have a couple ways to make $dis equal to $(this) in the context of the click.

The easiest is to simply have a global variable (or at least, in a scope that they both share) named $dis, and in your click event, set $dis = $(this) before you call checkMatch().

let $dis;
$('.card').click(() => {
  $dis = $(this);
  checkMatch();
});

Another, possibly cleaner approach is to simply call() the function and pass in this. You wouldn't have to use $dis at all, you could instead use $(this) directly:

$('.card').click(() => {
  checkMatch.call(this);
});

var checkMatch = function(){
  if ($clicked.length > 1){
    if ($card1 === $card2){
        $(this).toggleClass('match');
        $matched.push($clicked);
        console.log('MATCH');
        $clicked = [];
        console.log($matched);
        console.log($clicked);
    }else {
        $clicked = [];
        $('.card').removeClass('open show');
        console.log('NOT A MATCH!')
    };
  } else {

  };
};

Using call(), the first parameter is what this should mean inside of the function.

samanime
  • 25,408
  • 15
  • 90
  • 139
  • Thanks a lot! Do you have any way of fixing my issue that I described in the end part of the post? I would appreciate it because that's a huge issue of mine! – Cosmindru Nov 27 '17 at 21:10
0

sorry i overslept yesterday when i fix your code,

your question is only about $(this).

but when i looks your code i found some mistake, so i decide to fix them rather than only answer your question (just killing time before sleep)

samanime answer your question well, so i'm not explain that again.

here my code. looks ugly but i made it as simple as possible. maybe you can learn a lot here.

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Matching Game</title>
    <meta name="description" content="">
    <link rel="stylesheet prefetch" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.1/css/font-awesome.min.css">
    <link rel="stylesheet prefetch" href="https://fonts.googleapis.com/css?family=Coda">
    <!--<link rel="stylesheet" href="css/app.css">-->
    <style>
    html {
    box-sizing: border-box;
}

*,
*::before,
*::after {
    box-sizing: inherit;
}

html,
body {
    width: 100%;
    height: 100%;
    margin: 0;
    padding: 0;
}

body {
    /*background: #ffffff url('../img/geometry2.png');  Background pattern from Subtle Patterns */
    font-family: 'Coda', cursive;
}

.container {
    display: flex;
    justify-content: center;
    align-items: center;
    flex-direction: column;
}

h1 {
    font-family: 'Open Sans', sans-serif;
    font-weight: 300;
}

/*
 * Styles for the deck of cards
 */

.deck {
    width: 660px;
    min-height: 680px;
    background: linear-gradient(160deg, #02ccba 0%, #aa7ecd 100%);
    padding: 32px;
    border-radius: 10px;
    box-shadow: 12px 15px 20px 0 rgba(46, 61, 73, 0.5);
    display: flex;
    flex-wrap: wrap;
    justify-content: space-between;
    align-items: center;
    margin: 0 0 3em;
}

.deck .card {
    height: 125px;
    width: 125px;
    background: #2e3d49;
    font-size: 0;
    color: #ffffff;
    border-radius: 8px;
    cursor: pointer;
    display: flex;
    justify-content: center;
    align-items: center;
    box-shadow: 5px 2px 20px 0 rgba(46, 61, 73, 0.5);
}

.deck .card.open {
    transform: rotateY(0);
    background: #02b3e4;
    cursor: default;
}

.deck .card.show {
    font-size: 33px;
}

.deck .card.match {
    cursor: default;
    background: #02ccba;
    font-size: 33px;
}

.deck .card.wrong {
    animation: shake 1s cubic-bezier(0.075, 0.82, 0.165, 1) both;
}

.wrong {
    -webkit-animation-name: wiggle;
    -ms-animation-name: wiggle;
    -ms-animation-duration: 1000ms;
    -webkit-animation-duration: 1000ms;
    -webkit-animation-iteration-count: 1;
    -ms-animation-iteration-count: 1;
    -webkit-animation-timing-function: ease-in-out;
    -ms-animation-timing-function: ease-in-out;
}

@keyframes wiggle {
    0% {transform: rotate(10deg);}
    25% {transform: rotate(-10deg);}
    50% {transform: rotate(20deg);}
    75% {transform: rotate(-5deg);}
    100% {transform: rotate(0deg);}
}

/*
 * Styles for the Score Panel
 */

.score-panel {
    text-align: left;
    width: 345px;
    margin-bottom: 10px;
}

.score-panel .stars {
    margin: 0;
    padding: 0;
    display: inline-block;
    margin: 0 5px 0 0;
}

.score-panel .stars li {
    list-style: none;
    display: inline-block;
}

.score-panel .restart {
    float: right;
    cursor: pointer;
}
.loading{
    color: white;
    position: absolute;
    left: 35%;
    top: 50%;
}
.loading span{
    font-size: 72px;
    font-weight: bold;
}
    </style>
</head>
<body>

    <div class="container">
        <header>
            <h1>Matching Game</h1>
        </header>

        <section class="score-panel">
            <ul class="stars">
                <li><i class="fa fa-star"></i></li>
                <li><i class="fa fa-star"></i></li>
                <li><i class="fa fa-star"></i></li>
            </ul>

            <span class="moves">0</span> Moves

            <div class="restart">
                <i class="fa fa-repeat"></i>
            </div>
        </section>

        <ul class="deck"></ul>

    </div>
    <div class="loading"><i class="fa fa-refresh fa-spin fa-5x fa-fw"></i> <span class="msg">Loading...</span></div>

    <script
    src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.js"></script>
    <!--<script src="js/app.js"></script>-->
    <script>
    $(function(){
        var clicked = [];
        var preventClicked = false;
        var icons = ["fa-diamond", "fa-anchor", "fa-paper-plane-o", "fa-bolt", "fa-cube", "fa-leaf", "fa-bicycle", "fa-bomb"]; //must be 8

        function createGame(icons){
            if(icons.length == 8){
                $('.deck').html('');
                var box = 2* icons.length;
                var num = -1;
                for(a=0; a< icons.length; a++){
                    $('.deck').append('<li class="card" p="'+ a +'"><i class="fa '+ icons[a] +'"></i></li>');
                    $('.deck').append('<li class="card" p="'+ a +'"><i class="fa '+ icons[a] +'"></i></li>'); //twice per icon
                }
                setTimeout(function(){
                    $('.restart').click(); //shuffle now
                    $('.loading').hide();
                }, 500)
            }else{
                alert("error: icon must be 8");
            }
        }

        createGame(icons); //init the game

        // Shuffle function
        $('.restart').click(function () {
            var cards = $('.deck').find('.card');
            cards.removeClass('show open match');
            cards.sort(function () {
                return Math.random() - .5;
            });
            $('.deck').append(cards);
        });


        // Click event that runs functions
        $('.deck').on('click', '.card:not(.match):not(.open)', function(e){ //prevent match and open being clicked again
            if(preventClicked == false){
                preventClicked = true;
                $(this).addClass('open show');
                clicked.push(e.target);
                if(clicked.length > 1){
                    $('.moves').text(parseInt($('.moves').text()) + 1);
                    //checkMatch
                    if($(clicked[0]).attr('p') == $(clicked[1]).attr('p')){
                        $(this).addClass('match');
                        $(clicked[0]).addClass('match');
                        $(clicked[1]).addClass('match');
                        clicked = [];
                        preventClicked = false;
                    }else{
                        setTimeout(function(){
                            $(clicked[0]).removeClass('open show');
                            $(clicked[1]).removeClass('open show');
                            clicked = [];
                            preventClicked = false;
                        }, 800);
                    }
                }else{
                    preventClicked = false;
                }
            }               
        });
    });
    </script>
</body>
</html>
plonknimbuzz
  • 2,594
  • 2
  • 19
  • 31
  • Wow thanks a lot, your version works so much better and literally makes my code look like a joke. I would upvote you but I don't have enough rep. Thanks again. – Cosmindru Nov 28 '17 at 08:49