質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.86%

  • JavaScript

    14737questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • jQuery

    6133questions

    jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

  • HTML5

    3586questions

    HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

  • CSS3

    1844questions

    CSS(Cascading Style Sheet)の第3版です。CSS3と略されることが多いです。色やデザインを柔軟に変更することが可能になります。

jQuery 神経衰弱を作ったものの動かない

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 330

ysmd

score 6

発生している問題・エラーメッセージ

jQueryで神経衰弱を作ってみたものの動作しません。

動作の流れとしては以下の通りです。
① 16枚のカードの中から「?」と書かれたものをひとつクリック
② そのカードに書かれている「?」が「1」などの数字に変わる
③ もうひとつ「?」と書かれたものをクリックする
④ その要素に書かれている「?」が「1」などの数字に変わる
⑤ ②と④で表示された数字が一致している場合は、開いた数字はそのままで①に戻る。一致していない場合は1秒後に数字が「?」に戻り①にもどる。
⑥: 全ての要素が開かれたときにアラートで「Game Over」

ですが、現状は
カードをクリックしても「?」が数字に切り替わらず、2枚のカードをクリックすると途中クリック無効のコードが働き全てのカードがクリックできなくなってしまい先に進めません。

以下のサイトを参考に書いてみたのですが動作しません。
https://magnets.jp/web_design/6308/#midashi1

該当のソースコード

<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta name="format-detection" content="telephone=no">
<title></title>
<link rel="stylesheet" href="css/reset.css">
<link rel="stylesheet" href="css/base.css">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<ul class="lists clearfix"></ul>
<script type="text/javascript" src="js/jquery.js"></script>
<script type="text/javascript">
//jquery
</script>
</body>
</html>
.lists {
    border: 10px #CCC solid;
}
.lists > li {
    float: left;
    width: 25%;
    background-color: #EEE;
    border-top: 2px #CCC solid;
    border-right: 2px #CCC solid;
    font-size: 20px;
    font-weight: bold;
    line-height: 75px;
    text-align: center;
    cursor: pointer;
    -webkit-box-sizing: border-box;
    box-sizing: border-box;
}
.lists > li:nth-child(-n + 4) {
    border-top: none;
}
.lists > li:nth-child(4n) {
    border-right: none;
}
$(function(){
  var $ul = $(".lists"),
      totalCard = 16, //カード枚数
      cardNum = [], //カード配列
      returnSec = 1000, //めくったカードが戻る秒数
      index, //クリックしたカードの並び順
      first = true, //クリックしたカードが1枚目かどうかの判定
      card1,  //1枚目に引いたカードの番号
      card2,  //2枚目に引いたカードの番号
      pair = 0; //正解したカードのペア数

  //カード番号を配列に格納
  for (var i = 1; i <= totalCard/2; i++){
    cardNum.push(i,i);
  }
  //配列の中身をランダムに並び替える
  cardNum.sort(function(){
    return Math.random() - Math.random();
  });
  //カードを追加
  var listItems = cardNum.map(function(num){
    return "<li data-num='" + num + "'>?</li>";
  });
  $ul.append(listItems);

    // カードを開く
  function open(){
    $('li').click(function(){
      $(this).text($(this).data('num'));
    });
  }
  // カードを閉じる
  function cardClose(){
    setTimeout(function(){
      $('li').text('?');
    },returnSec);
  }
  //カードをクリックさせない
  function cardLock(){
    $('.lists li:eq('+index+')').css('pointer-events','none');
  }  
  //すべてのカードをロック
  function allLock(){
    $('.lists li').css('pointer-events','none');
  }
  //全てのカードをアンロック
  function unLock(){
    $('.lists li').css('','');
  }
  $('.lists li').click(function(){
    index = $('.lists li').index(this);
    cardLock();
    cardClose(index,open);
    if(first == true){
      index1 = index;
      card1 = cardNum[index];
      first = false;
    } else {
      allLock();
      card2 = cardNum[index];
      comparison();
    }
  });
  //選んだカード2枚の正否判定
  function comparison(){
    if(card1 == card2){ //同じカードだったら
      $('.lists li:eq('+index+')').css('pointer-events','none');
      $('.lists li:eq('+index1+')').css('pointer-events','none');
      pair++;
      if(pair == totalCard/2){
        setTimeout(function(){
          alert('Game Over')
        },returnSec);
      }
    } else { //違うカードだったら
      setTimeout(function(){
        cardClose(index,close);
        cardClose(index1,close);
      },returnSec);
    }
    first = true;
    card2 = 0;
    setTimeout(function(){
      unLock();
    }, returnSec);
  }
});

補足情報(言語/FW/ツール等のバージョンなど)

参考にしたものをほぼ写経して、不要なもの(imgなど使わないもの)は省いて書いたのですが、
動作しない原因が分からない状況のためアドバイスをいただきたいです。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • kei344

    2018/01/23 15:06

    エラーは出ていませんか?デベロッパーツールで確認してみてください。http://eng-entrance.com/javascript-display-error また、「うまくできない」とは「何をしたときに」「どうなると思って」「どうなったのか」を具体的に記述されたほうが回答を得られやすいと思います。

    キャンセル

  • ysmd

    2018/01/23 15:35

    ご指摘ありがとうございます。伝わりやすいように追記しました。コンソール上にはエラーは出ていませんでした。

    キャンセル

回答 2

checkベストアンサー

+2

ソースコードを拝見しましたが、大分、参考にされたソース?とは違うようです。

関数定義とイベント登録と実際の処理とがごちゃ混ぜになっているので、非常にわかりづらくなってしまっています。

要は大まかな処理の流れとしては、以下であれば言い訳です。

  1. カード部分の作成
  2. カードをクリックされた時のイベントを登録
    2-1. クリックされたカードを表にする
    2-2. カードを比較

以下に参考としてソースを書いておきます。

function open($card){
  $card.css('pointer-events','none')
       .text($card.data('num'));

}

function close($card){
  $card.css('pointer-events','')
       .text('?');
}


function compare($card){
    // 1枚目に開いたカードが存在するか確認
    // 存在すれば、即ち、現在は2枚目のカードを開いたところ 
    if($('.firstOpen').length == 0){
      // 開いたカードが一枚目のカードであれば、
      // この要素が1枚目であることがわかるようにするため、
      // firstOpenのクラスを付与しておく
      $card.addClass('firstOpen');
    } else {

      // 1枚目のカードのjQueryオブジェクト
      let $firstCard = $('.firstOpen');
      // 2枚目のカードのjQueryオブジェクト
      let $secondCard = $card;

      // 1枚目のカードの数字
      let firstNum = $firstCard.data('num');
      // 2枚目のカードの数字
      let secondNum = $secondCard.data('num');

      // 1枚目識別用のクラスを削除
      $firstCard.removeClass('firstOpen');

      // 一致している場合、両方からunopenedを削除する
      // その後、unopenedが付与された要素の数を確認し、
      // 0個であれば、アラートを表示する
      if(firstNum === secondNum){
        $firstCard.removeClass('unopened');
        $secondCard.removeClass('unopened');

        if($('.unopened').length ===0){
          alert("Game Over");
        }

        // 一致していない場合、二枚とも閉じる
      } else {
        close($firstCard);
        close($secondCard);
      }

    }

}

// 初期処理
$(function(){

  let cardNum = [];
  let totalCard = 16;

  // カードの中身を作成
  for (var i = 1; i <= totalCard/2; i++){
    cardNum.push(i,i);
  }

  // ランダムに並べ替えて
  // li要素を作成して
  // listに追加
  cardNum
    .sort(function(){
        return Math.random() - Math.random();
      })
    .map(function(num){
        return "<li class='unopened' data-num='" + num + "'>?</li>";
      })
    .forEach(function(element){
        $(".lists").append(element);
      });

  // カードをクリックされた時のイベントを登録
  $('.lists li').click(function(){
    // クリックされたカード(li要素)のjQueryオブジェクト
    let $openedCard = $(this);

    // カードをオープン
    open($openedCard);

    // カードを比較
    // 1秒ほど待機させてから比較させる
    // ※待機しないと二枚目のカードの番号が表示されるとほぼ同時ぐらいに比較が終わり
    // 二枚目のカードの数字がわかりにくいため
    setTimeout(function(){compare($openedCard);}, 1000);

  });
});

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/01/23 22:12

    回答ありがとうございます。
    一つ一つ説明していただき助かりました。
    とても勉強になります。

    キャンセル

+1

open() がどこでも使われていないから1度も開かないと思います。
各関数に console.log(変数) を仕込んで、状態がどうなっているか1つずつ確認してみてはいかがでしょうか。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/01/23 16:50 編集

    回答ありがとうございます。
    openという関数化した使い方をせずに、function open(){}を外したらクリック時にちゃんと数字に変わりました。
    その後の挙動はカードを1枚クリックすると「?」に戻り、開いたままを維持することができない状態です。2枚目をクリックしても同様で、2枚クリック後は全てクリックできなくなります。console.log()で確認しても決定打になる答えは見つけられませんでした。
    お手すきの時にまたアドバイスをいただけないでしょうか。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.86%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • JavaScript

    14737questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • jQuery

    6133questions

    jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

  • HTML5

    3586questions

    HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

  • CSS3

    1844questions

    CSS(Cascading Style Sheet)の第3版です。CSS3と略されることが多いです。色やデザインを柔軟に変更することが可能になります。