I was building a quiz module for one website. It is a simple true/false statements where you first choose the answer, the correct answer is displayed, and then you can move forward to the next question.
For better understanding, please find working code snippet here.
I need mentor guidance in order to make my existing code shorter and optimized.
Here is the jQuery code for this quiz module:
var flag = $('.quiz ul'),
currentPosition = 0,
currentQuestion = 0,
slideWidth = 200,
option = $('.flag'),
tryCTA = $('.CTAtry'),
nextQuestion = $('.next'),
answer = $('span.answer')
questionWrapper = $('.quiz ul'),
totalQuestions = $('.quiz ul li').length,
answers = ["True","False","False"];
//Set UL width
questionWrapper.css('width',totalQuestions*slideWidth)
option.on('click',function(e) {
e.preventDefault();
var nextCTA = $(this).parent().next(nextQuestion).length,
optionWrapper = $(this).parent();
if(nextCTA) {
optionWrapper.next(nextQuestion).show();
} else {
tryCTA.show();
}
optionWrapper.parent().find(answer).html(answers[currentQuestion]).show();
optionWrapper.hide();
});
nextQuestion.on('click',function(e){
e.preventDefault();
currentPosition = currentPosition+1;
$(this).parent().parent().animate({
'marginLeft' : slideWidth*(-currentPosition)
});
currentQuestion++;
});
tryCTA.on('click',function(e) {
e.preventDefault();
resetQuiz(e);
$(this).hide();
})
function resetQuiz(e) {
$('.quiz ul').animate({
opacity: 0
},0)
.animate({
opacity: 1
},500)
$('span.answer').html(" ");
$('.quiz ul').css('margin-left','0');
$('.options').show();
$('.next').hide();
currentPosition = 0;
currentQuestion = 0;
}
HTML:
<div class="quiz">
<ul>
<li>
<span class="answer"></span>
<p>Writing Object Oriented JavaScript is not a FUN.</p>
<div class="options">
<a href="" class="flag">True</a>
<span>or</span>
<a href="" class="flag">False</a>
</div>
<a href="" class="next">Next</a>
</li>
<li>
<span class="answer"></span>
<p>Let's give it a try! No harm in learning anything NEW.</p>
<div class="options">
<a href="" class="flag">True</a>
<span>or</span>
<a href="" class="flag">False</a>
</div>
<a href="" class="next">Next</a>
</li>
<li>
<span class="answer"></span>
<p>Some code running !</p>
<div class="options">
<a href="" class="flag">True</a>
<span>or</span>
<a href="" class="flag">False</a>
</div>
</li>
</ul>
<a href="" class="CTAtry">Try Again!</a>
</div>
1 Answer 1
Overall this is already pretty well organized and compact. There isn't a lot of duplication or obvious abstractions that can be made. It would be helpful to see the HTML to see if there are any changes that would make the Javascript easier to write.
A couple of suggestions:
Wrap the entire code block in an IIFE to avoid cluttering global namespace
(function (,ドル undefined) { // Your code here ... } (jQuery));
Use
.width()
instead of.css('width', ...)
Some of your variables are only being referenced once and can be inlined:
$('.flag').on('click', ...); // etc.
-
\$\begingroup\$ About 4, he cannot merge them because the
.show()
is applied to the "answer" inside the "optionWrapper", and the hide is applied to the "optionWrapper". But yes, the.show()
feels redundant. \$\endgroup\$ANeves– ANeves2012年06月01日 08:29:07 +00:00Commented Jun 1, 2012 at 8:29 -
\$\begingroup\$ @pgraham thanks a lot for your feedback. I will definitely incorporate your points and post the updated code by tomorrow. Only thing where i need some guidance is "Why are we passing 'undefined' with $"?? any specific reason ?? \$\endgroup\$Lokesh Yadav– Lokesh Yadav2012年06月01日 10:16:54 +00:00Commented Jun 1, 2012 at 10:16
-
1\$\begingroup\$ passing undefined and then not providing a value for it is a way of protecting against
undefined = 'A defined value';
or similar somewhere in previous code. It is not strictly necessary but ensures thatundefined
is actuallyundefined
within that block of code. \$\endgroup\$pgraham– pgraham2012年06月02日 14:09:34 +00:00Commented Jun 2, 2012 at 14:09