我向那些到目前为止读过这个问题的人道歉(10次观看)。我还不确定在测验配置中传递的语法,但她显然允许它。
我尝试进行一些小改动,以便slickQuiz plugin在同一页面上支持多个quizes,author 3 years suggested it probably can do.但是它会在相同的测验问题中加载它似乎是由于在slickQuiz-config.js文件中定义了quizJSON:
// Setup your quiz text and questions here
var quizJSON = {
"info": {
"name": "Test Your Knowledge!!",
"main": "<p>Think you're smart enough to be on Jeopardy?
... continues on ...
}
};
&#13;
以及slickQuiz.js中的以下行,显然不允许加载的quizJSON配置存在可变性:
// Set via json option or quizJSON variable (see slickQuiz-config.js)
var quizValues = (plugin.config.json ? plugin.config.json : typeof quizJSON != 'undefined' ? quizJSON : null);
我对Javascript很新,我不知道如何传递内容来设置quizValues使用哪个测验配置(问题/答案)文件。请注意,插件包含一个很小的master.js文件,看起来我可以为每个测验设置不同的ID:
// master.js file -- originally just defined #slickQuiz
$(function () {
$('#slickQuiz').slickQuiz();
});
$(function () {
$('#slickQuiz2').slickQuiz();
});
但是如何将参数传递给slickQuiz(),我可以在slickQuiz.js中使用?这可能是微不足道的,但调用函数的方式及其选项让我对JS不熟悉。
请注意,在插件的示例html文件中如何使用slickQuiz id:
<!DOCTYPE html>
<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="content-type">
<title>SlickQuiz Demo</title>
<link href="css/reset.css" media="screen" rel="stylesheet" type="text/css">
<link href="css/slickQuiz.css" media="screen" rel="stylesheet" type="text/css">
<link href="css/master.css" media="screen" rel="stylesheet" type="text/css">
</head>
<body id="slickQuiz">
<h1 class="quizName"><!-- where the quiz name goes --></h1>
<div class="quizArea">
<div class="quizHeader">
<!-- where the quiz main copy goes -->
<a class="button startQuiz" href="#">Get Started!</a>
</div>
<!-- where the quiz gets built -->
</div>
<div class="quizResults">
<h3 class="quizScore">You Scored: <span><!-- where the quiz score goes --></span></h3>
<h3 class="quizLevel"><strong>Ranking:</strong> <span><!-- where the quiz ranking level goes --></span></h3>
<div class="quizResultsCopy">
<!-- where the quiz result copy goes -->
</div>
</div>
<script src="js/jquery.js"></script>
<script src="js/slickQuiz-config.js"></script>
<script src="js/slickQuiz.js"></script>
<script src="js/master.js"></script>
</body>
</html>
&#13;
这是slickQuiz.js文件的大部分内容(只允许复制,在上面的链接中休息):
/*!
* SlickQuiz jQuery Plugin
(function($){
$.slickQuiz = function(element, options) {
var plugin = this,
$element = $(element),
_element = '#' + $element.attr('id'),
defaults = {
checkAnswerText: 'Check My Answer!',
nextQuestionText: 'Next »',
backButtonText: '',
completeQuizText: '',
tryAgainText: '',
questionCountText: 'Question %current of %total',
preventUnansweredText: 'You must select at least one answer.',
questionTemplateText: '%count. %text',
scoreTemplateText: '%score / %total',
nameTemplateText: '<span>Quiz: </span>%name',
skipStartButton: false,
numberOfQuestions: null,
randomSortQuestions: false,
randomSortAnswers: false,
preventUnanswered: false,
disableScore: false,
disableRanking: false,
scoreAsPercentage: false,
perQuestionResponseMessaging: true,
perQuestionResponseAnswers: false,
completionResponseMessaging: false,
displayQuestionCount: true, // Deprecate?
displayQuestionNumber: true, // Deprecate?
animationCallbacks: { // only for the methods that have jQuery animations offering callback
setupQuiz: function () {},
startQuiz: function () {},
resetQuiz: function () {},
checkAnswer: function () {},
nextQuestion: function () {},
backToQuestion: function () {},
completeQuiz: function () {}
},
events: {
onStartQuiz: function (options) {},
onCompleteQuiz: function (options) {} // reserved: options.questionCount, options.score
}
},
// Class Name Strings (Used for building quiz and for selectors)
questionCountClass = 'questionCount',
questionGroupClass = 'questions',
questionClass = 'question',
answersClass = 'answers',
responsesClass = 'responses',
completeClass = 'complete',
correctClass = 'correctResponse',
incorrectClass = 'incorrectResponse',
correctResponseClass = 'correct',
incorrectResponseClass = 'incorrect',
checkAnswerClass = 'checkAnswer',
nextQuestionClass = 'nextQuestion',
lastQuestionClass = 'lastQuestion',
backToQuestionClass = 'backToQuestion',
tryAgainClass = 'tryAgain',
// Sub-Quiz / Sub-Question Class Selectors
_questionCount = '.' + questionCountClass,
_questions = '.' + questionGroupClass,
_question = '.' + questionClass,
_answers = '.' + answersClass,
_answer = '.' + answersClass + ' li',
_responses = '.' + responsesClass,
_response = '.' + responsesClass + ' li',
_correct = '.' + correctClass,
_correctResponse = '.' + correctResponseClass,
_incorrectResponse = '.' + incorrectResponseClass,
_checkAnswerBtn = '.' + checkAnswerClass,
_nextQuestionBtn = '.' + nextQuestionClass,
_prevQuestionBtn = '.' + backToQuestionClass,
_tryAgainBtn = '.' + tryAgainClass,
// Top Level Quiz Element Class Selectors
_quizStarter = _element + ' .startQuiz',
_quizName = _element + ' .quizName',
_quizArea = _element + ' .quizArea',
_quizResults = _element + ' .quizResults',
_quizResultsCopy = _element + ' .quizResultsCopy',
_quizHeader = _element + ' .quizHeader',
_quizScore = _element + ' .quizScore',
_quizLevel = _element + ' .quizLevel',
// Top Level Quiz Element Objects
$quizStarter = $(_quizStarter),
$quizName = $(_quizName),
$quizArea = $(_quizArea),
$quizResults = $(_quizResults),
$quizResultsCopy = $(_quizResultsCopy),
$quizHeader = $(_quizHeader),
$quizScore = $(_quizScore),
$quizLevel = $(_quizLevel)
;
// Reassign user-submitted deprecated options
var depMsg = '';
if (options && typeof options.disableNext != 'undefined') {
if (typeof options.preventUnanswered == 'undefined') {
options.preventUnanswered = options.disableNext;
}
depMsg += 'The \'disableNext\' option has been deprecated, please use \'preventUnanswered\' in it\'s place.\n\n';
}
if (options && typeof options.disableResponseMessaging != 'undefined') {
if (typeof options.preventUnanswered == 'undefined') {
options.perQuestionResponseMessaging = options.disableResponseMessaging;
}
depMsg += 'The \'disableResponseMessaging\' option has been deprecated, please use' +
' \'perQuestionResponseMessaging\' and \'completionResponseMessaging\' in it\'s place.\n\n';
}
if (options && typeof options.randomSort != 'undefined') {
if (typeof options.randomSortQuestions == 'undefined') {
options.randomSortQuestions = options.randomSort;
}
if (typeof options.randomSortAnswers == 'undefined') {
options.randomSortAnswers = options.randomSort;
}
depMsg += 'The \'randomSort\' option has been deprecated, please use' +
' \'randomSortQuestions\' and \'randomSortAnswers\' in it\'s place.\n\n';
}
if (depMsg !== '') {
if (typeof console != 'undefined') {
console.warn(depMsg);
} else {
alert(depMsg);
}
}
// End of deprecation reassignment
plugin.config = $.extend(defaults, options);
// Set via json option or quizJSON variable (see slickQuiz-config.js)
var quizValues = (plugin.config.json ? plugin.config.json : typeof quizJSON != 'undefined' ? quizJSON : null);
// Get questions, possibly sorted randomly
var questions = plugin.config.randomSortQuestions ?
quizValues.questions.sort(function() { return (Math.round(Math.random())-0.5); }) :
quizValues.questions;
// Count the number of questions
var questionCount = questions.length;
// Select X number of questions to load if options is set
if (plugin.config.numberOfQuestions && questionCount >= plugin.config.numberOfQuestions) {
questions = questions.slice(0, plugin.config.numberOfQuestions);
questionCount = questions.length;
}
// some special private/internal methods
var internal = {method: {
// get a key whose notches are "resolved jQ deferred" objects; one per notch on the key
// think of the key as a house key with notches on it
getKey: function (notches) { // returns [], notches >= 1
var key = [];
for (i=0; i<notches; i++) key[i] = $.Deferred ();
return key;
},
// put the key in the door, if all the notches pass then you can turn the key and "go"
turnKeyAndGo: function (key, go) { // key = [], go = function ()
// when all the notches of the key are accepted (resolved) then the key turns and the engine (callback/go) starts
$.when.apply (null, key). then (function () {
go ();
});
},
// get one jQ
getKeyNotch: function (key, notch) { // notch >= 1, key = []
// key has several notches, numbered as 1, 2, 3, ... (no zero notch)
// we resolve and return the "jQ deferred" object at specified notch
return function () {
key[notch-1].resolve (); // it is ASSUMED that you initiated the key with enough notches
};
}
}};
plugin.method = {
// Sets up the questions and answers based on above array
setupQuiz: function(options) { // use 'options' object to pass args
var key, keyNotch, kN;
key = internal.method.getKey (3); // how many notches == how many jQ animations you will run
keyNotch = internal.method.getKeyNotch; // a function that returns a jQ animation callback function
kN = keyNotch; // you specify the notch, you get a callback function for your animation
$quizName.hide().html(plugin.config.nameTemplateText
.replace('%name', quizValues.info.name) ).fadeIn(1000, kN(key,1));
$quizHeader.hide().prepend($('<div class="quizDescription">' + quizValues.info.main + '</div>')).fadeIn(1000, kN(key,2));
$quizResultsCopy.append(quizValues.info.results);
// add retry button to results view, if enabled
if (plugin.config.tryAgainText && plugin.config.tryAgainText !== '') {
$quizResultsCopy.append('<p><a class="button ' + tryAgainClass + '" href="#">' + plugin.config.tryAgainText + '</a></p>');
}
// Setup questions
var quiz = $('<ol class="' + questionGroupClass + '"></ol>'),
count = 1;
// Loop through questions object
for (i in questions) {
if (questions.hasOwnProperty(i)) {
var question = questions[i];
var questionHTML = $('<li class="' + questionClass +'" id="question' + (count - 1) + '"></li>');
if (plugin.config.displayQuestionCount) {
questionHTML.append('<div class="' + questionCountClass + '">' +
plugin.config.questionCountText
.replace('%current', '<span class="current">' + count + '</span>')
.replace('%total', '<span class="total">' +
questionCount + '</span>') + '</div>');
}
var formatQuestion = '';
if (plugin.config.displayQuestionNumber) {
formatQuestion = plugin.config.questionTemplateText
.replace('%count', count).replace('%text', question.q);
} else {
formatQuestion = question.q;
}
questionHTML.append('<h3>' + formatQuestion + '</h3>');
// Count the number of true values
var truths = 0;
for (i in question.a) {
if (question.a.hasOwnProperty(i)) {
answer = question.a[i];
if (answer.correct) {
truths++;
}
}
}
// Now let's append the answers with checkboxes or radios depending on truth count
var answerHTML = $('<ul class="' + answersClass + '"></ul>');
// Get the answers
var answers = plugin.config.randomSortAnswers ?
question.a.sort(function() { return (Math.round(Math.random())-0.5); }) :
question.a;
// prepare a name for the answer inputs based on the question
var selectAny = question.select_any ? question.select_any : false,
forceCheckbox = question.force_checkbox ? question.force_checkbox : false,
checkbox = (truths > 1 && !selectAny) || forceCheckbox,
inputName = $element.attr('id') + '_question' + (count - 1),
inputType = checkbox ? 'checkbox' : 'radio';
if( count == quizValues.questions.length ) {
nextQuestionClass = nextQuestionClass + ' ' + lastQuestionClass;
}
for (i in answers) {
if (answers.hasOwnProperty(i)) {
answer = answers[i],
optionId = inputName + '_' + i.toString();
// If question has >1 true answers and is not a select any, use checkboxes; otherwise, radios
var input = '<input id="' + optionId + '" name="' + inputName +
'" type="' + inputType + '" /> ';
var optionLabel = '<label for="' + optionId + '">' + answer.option + '</label>';
var answerContent = $('<li></li>')
.append(input)
.append(optionLabel);
answerHTML.append(answerContent);
}
}
// Append answers to question
questionHTML.append(answerHTML);
// If response messaging is NOT disabled, add it
if (plugin.config.perQuestionResponseMessaging || plugin.config.completionResponseMessaging) {
// Now let's append the correct / incorrect response messages
var responseHTML = $('<ul class="' + responsesClass + '"></ul>');
responseHTML.append('<li class="' + correctResponseClass + '">' + question.correct + '</li>');
responseHTML.append('<li class="' + incorrectResponseClass + '">' + question.incorrect + '</li>');
// Append responses to question
questionHTML.append(responseHTML);
}
// Appends check answer / back / next question buttons
if (plugin.config.backButtonText && plugin.config.backButtonText !== '') {
questionHTML.append('<a href="#" class="button ' + backToQuestionClass + '">' + plugin.config.backButtonText + '</a>');
}
var nextText = plugin.config.nextQuestionText;
if (plugin.config.completeQuizText && count == questionCount) {
nextText = plugin.config.completeQuizText;
}
// If we're not showing responses per question, show next question button and make it check the answer too
if (!plugin.config.perQuestionResponseMessaging) {
questionHTML.append('<a href="#" class="button ' + nextQuestionClass + ' ' + checkAnswerClass + '">' + nextText + '</a>');
} else {
questionHTML.append('<a href="#" class="button ' + nextQuestionClass + '">' + nextText + '</a>');
questionHTML.append('<a href="#" class="button ' + checkAnswerClass + '">' + plugin.config.checkAnswerText + '</a>');
}
// Append question & answers to quiz
quiz.append(questionHTML);
count++;
}
}
// Add the quiz content to the page
$quizArea.append(quiz);
// Toggle the start button OR start the quiz if start button is disabled
if (plugin.config.skipStartButton || $quizStarter.length == 0) {
$quizStarter.hide();
plugin.method.startQuiz.apply (this, [{callback: plugin.config.animationCallbacks.startQuiz}]); // TODO: determine why 'this' is being passed as arg to startQuiz method
kN(key,3).apply (null, []);
} else {
$quizStarter.fadeIn(500, kN(key,3)); // 3d notch on key must be on both sides of if/else, otherwise key won't turn
}
internal.method.turnKeyAndGo (key, options && options.callback ? options.callback : function () {});
},
// Starts the quiz (hides start button and displays first question)
startQuiz: function(options) {
var key, keyNotch, kN;
key = internal.method.getKey (1); // how many notches == how many jQ animations you will run
keyNotch = internal.method.getKeyNotch; // a function that returns a jQ animation callback function
kN = keyNotch; // you specify the notch, you get a callback function for your animation
function start(options) {
var firstQuestion = $(_element + ' ' + _questions + ' li').first();
if (firstQuestion.length) {
firstQuestion.fadeIn(500, function () {
if (options && options.callback) options.callback ();
});
}
}
if (plugin.config.skipStartButton || $quizStarter.length == 0) {
start({callback: kN(key,1)});
} else {
$quizStarter.fadeOut(300, function(){
start({callback: kN(key,1)}); // 1st notch on key must be on both sides of if/else, otherwise key won't turn
});
}
internal.method.turnKeyAndGo (key, options && options.callback ? options.callback : function () {});
if (plugin.config.events &&
plugin.config.events.onStartQuiz) {
plugin.config.events.onStartQuiz.apply (null, []);
}
},
*** had to delete code because stackoverflow limits what I can put into a question,
here is the end of the slickQuiz file found at the link above:
plugin.init();
};
$.fn.slickQuiz = function(options) {
return this.each(function() {
if (undefined === $(this).data('slickQuiz')) {
var plugin = new $.slickQuiz(this, options);
$(this).data('slickQuiz', plugin);
}
});
};
})(jQuery);
&#13;