3
\$\begingroup\$

I'm building a hotspot game, where users click on an area of an image, a text box appears and the user can type what they think the answer is.

If the answer is correct, 1 point is added to the user's score, and the hotspot is rendered unclickable.

I've made a start on the basic idea here:

https://codepen.io/Punchyoual/pen/oGXqyg

HTML

<div class="cat_container">
  <div id="score-container">
    <div id="score"></div>/10</div>


  <div class="hotspot hotspot_1 clickable1"></div>
  <div class="hotspot hotspot_2 clickable2"></div>
  <div class="hotspot hotspot_3 clickable3"></div>

  <div class="guess_box1 guess">
    <a class="close" id="close_guess_box1">X</a>
    <input type="text" class="answer" id="hotspot_1_answer"></input>
  </div>

  <div class="guess_box2 guess">
    <a class="close" id="close_guess_box2">X</a>
    <input type="text" class="answer" id="hotspot_2_answer"></input>
  </div>

  <div class="guess_box3 guess">
    <a class="close" id="close_guess_box3">X</a>
    <input type="text" class="answer" id="hotspot_3_answer"></input>
  </div>


  <div id="correct" style="display:none;"><H1 style="padding-top:160px;">Correct!</H1></div>
  <div id="incorrect" style="display:none;"><H1 style="padding-top:160px;">You're Wrong!<H1></div>
</div>
</div>

jQuery

$(".close").click(function() {
  $(".answer").val('');
});

//Click Areas

$(".clickable1").click(function() {
  $(".guess_box1").show();
  $('#hotspot_1_answer').focus();
  $(".guess").not(".guess_box1").each(function(){
    $(this).hide();
  })
});

$(".clickable2").click(function() {
  $(".guess_box2").show();
   $('#hotspot_2_answer').focus();
  $(".guess").not(".guess_box2").each(function(){
    $(this).hide();
  })
});

$(".clickable3").click(function() {
  $(".guess_box3").show();
   $('#hotspot_3_answer').focus();
  $(".guess").not(".guess_box3").each(function(){
    $(this).hide();
  })
});

//Close Guess boxes

$("#close_guess_box1").click(function() {
  $(".guess_box1").hide(300);
});

$("#close_guess_box2").click(function() {
  $(".guess_box2").hide(300);
});

$("#close_guess_box3").click(function() {
  $(".guess_box3").hide(300);
});



var score = 0;


$("#score").text(score);

$("#hotspot_1_answer").keypress(function(e) {

  if (e.which == 13) {

    var text = $('#hotspot_1_answer').val().toLowerCase();
    if (text == 'eye') {

      $(".guess_box1").remove();
      $("#answer_box").show();
      $("#correct").show();
      $(".hotspot_1").removeClass('clickable').addClass('hotspot_done'); 
      $('#correct').delay(1000).fadeOut();
      score++;
      $("#score").text(score);


    } else {

      $(".guess_box1").hide(100);
      $("#answer_box").show();
      $("#incorrect").show();
      $('#incorrect').delay(1000).fadeOut();
      $("#hotspot_1_answer").val('');

    }
  }
});

$("#hotspot_2_answer").keypress(function(e) {

  if (e.which == 13) {

    var text = $('#hotspot_2_answer').val().toLowerCase();
    if (text == 'ear') {

      $(".guess_box2").remove();
      $("#answer_box").show();
      $("#correct").show();
      $(".hotspot_2").removeClass('clickable').addClass('hotspot_done'); 
      $('#correct').delay(1000).fadeOut();
      score++;
      $("#score").text(score);


    } else {

      $(".guess_box2").hide(100);
      $("#answer_box").show();
      $("#incorrect").show();
      $('#incorrect').delay(1000).fadeOut();
      $("#hotspot_2_answer").val('');

    }
  }
});

$("#hotspot_3_answer").keypress(function(e) {

  if (e.which == 13) {

    var text = $('#hotspot_3_answer').val().toLowerCase();
    if (text == 'tail') {

      $(".guess_box3").remove();
      $("#answer_box").show();
      $("#correct").show();
      $(".hotspot_3").removeClass('clickable').addClass('hotspot_done'); 
      $('#correct').delay(1000).fadeOut();
      score++;
      $("#score").text(score);


    } else {

      $(".guess_box3").hide(100);
      $("#answer_box").show();
      $("#incorrect").show();
      $('#incorrect').delay(1000).fadeOut();
      $("#hotspot_3_answer").val('');

    }
  }
});

I'm sure there must be a more elegant solution to this, without using multiple answer boxes. I feel like i need to use data-attributes, and check the answer with JQuery, but i'm not really sure how.

\$\endgroup\$
1
\$\begingroup\$

First, we don't need to write seperate click events for every clickable area as that generate redundent code. Just have a common class in all clickable area and bind it to a single event handler and check which clickable area is being clicked in code.

HTML

<div class="hotspot hotspot_1 clickable"></div>
<div class="hotspot hotspot_2 clickable"></div>
<div class="hotspot hotspot_3 clickable"></div>

jQuery

let lastClickedClass = '';
$(".clickable").click(function () { 
    if($(this).hasClass('hotspot_1')){
        lastClickedClass = '.hotspot_1';
    }else if ($(this).hasClass('hotspot_2')){
        lastClickedClass = '.hotspot_2';
    }else if ($(this).hasClass('hotspot_3')){
        lastClickedClass = '.hotspot_3';
    }

    $(".guess_box").show();
    $('#hotspot_answer').focus();
    $(".guess").not(".guess_box").each(function () {
        $(this).hide();
    })
});

Next, We don't need different input for answers, as that will just increase number of input for every clickable area you add on the page. So you can just have one guess_box with the input and one keypress event to bind to.

HTML

<div class="guess_box guess">
    <a class="close" id="close_guess_box">X</a>
    <input type="text" class="answer" id="hotspot_answer">
</div>

jQuery

$("#hotspot_answer").keypress(function(e) {
    if (e.which == 13) {
        var text = $('#hotspot_answer').val().toLowerCase();
        var isCorrect = true;
        if(!((text === 'eye' && lastClickedClass==='.hotspot_1') 
            || (text === 'ear' && lastClickedClass==='.hotspot_2') 
            || (text === 'tail' && lastClickedClass==='.hotspot_3'))){
                isCorrect = false;
        }

        if (isCorrect) {
            $(".guess_box").hide();
            $("#hotspot_answer").val('');
            $("#answer_box").show();
            $("#correct").show();                    
            $(lastClickedClass).off('click');
            $('#correct').delay(1000).fadeOut();
            score++;
            $("#score").text(score);
        } else {
            $(".guess_box").hide(100);
            $("#answer_box").show();
            $("#incorrect").show();
            $('#incorrect').delay(1000).fadeOut();
            $("#hotspot_answer").val('');
        }
    }
});

Here's a fiddle for the same.

Hope this helps.

| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ This works - so much more efficient than my method! \$\endgroup\$ – user3113415 Sep 22 '17 at 9:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.