我想在固定布局的 epub3 电子书中的一章末尾进行测验。该测验将跨越多个页面,本质上是多项选择。每个问题将由问题本身和四个选项组成,每个选项都有一个单选按钮。在测验结束时,用户将单击一个按钮以显示他们的总体结果。为此,我需要在页面之间共享信息。一种方法是将所有页面放在一个 XHTML 文档中,然后我可以将学生对每个问题给出的答案存储在一个 javascript 变量中。但是,在同一个 XHTML 文件中包含多页固定布局的 epub3 书籍是否有效?正如我在这里所做的那样:
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops">
<head>
<title>My Book</title>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<style>
p.pagebreak {
page-break-after:always;
}
</style>
</head>
<body>
<p>
Text on Page 1
</p>
<p class="pagebreak"></p>
<p>
Text on Page 2
</p>
<p class="pagebreak"></p>
<p>
Text on Page 3
</p>
</body>
</html>
在 iBooks 中看起来不错。
或者,如果使用多个页面,我可以使用 window.sessionStorage
存储学生的答案。但是,我不知道有多少读者支持存储。我希望该测验适用于 iBooks 以及 Android 和 Windows 平板电脑和台式机。
您建议我如何实现测验?
最佳答案
我认为您并不真正了解实现和支持使用 ePub 有多么复杂。我想推荐你阅读 about ePub file format .查看最新版本ePub format规范也。
ePub 出版物(包括 ePub3)作为单个文件交付。此文件是一个未加密的压缩存档,其中包含一组相互关联的资源。
ePub 文件结构示例:
--ZIP Container--
mimetype
META-INF/
container.xml
OEBPS/
content.opf
chapter1.xhtml
ch1-pic.png
css/
style.css
myfont.otf
toc.ncx
Citate from your question: I would like the quiz to work for iBooks and also for Android and Windows Tablets and Desktops.
浏览器本身不支持读取和显示此类文件。如果你真的想要这个,那么你必须对所有这些进行编程。这对你来说并不是必需的,因为我们已经有了 JavaScript 库:
- Epub.js - 用于在浏览器中呈现 ePub 文档的 JavaScript 库;
- Readium-js - 用 Javascript 编写的 EPUB 处理引擎
但不要忘记:在这两种情况下,它们都需要一个 NodeJS 服务器作为先决条件。
那你得想想这个过程的所有资源——实在是太多了!太多的开发工作、太多的资源和太多的能源浪费!
因为这一切,没有人以这种方式去做。
Citate from your question: How would you advise I implement my quiz?
我推荐的方案
您可以将测验的所有问题都放在一个 HTML 文件中,并且可以将所有答案保存在数组中。我已经为您准备了演示示例:
var activePage = 0,
pages = document.querySelectorAll('.quiz-page'),
answers = [];
function goToNext(buttonObj)
{
var questions = document.getElementsByName('question' + activePage),
value = -1;
for(var i = 0; i < questions.length; i++)
if(questions[i].checked)
value = questions[i].value;
if(value < 0)
{
alert('Please choose one value!');
return;
}
else
// save the answer in array
answers[activePage] = value;
activePage++;
for(var i = 0; i < pages.length; i++)
pages[i].style.display = 'none';
if(activePage < pages.length)
pages[activePage].style.display = 'block';
else
{
buttonObj.style.display = 'none';
sendResultsToServer();
}
if(activePage == pages.length - 1)
buttonObj.value = 'Get Results';
}
function sendResultsToServer()
{
var strAllAnswers = answers.join(',');
console.log('Answers indexes (one on each page): ' + strAllAnswers);
//TODO: Send results to server using AJAX
//... your AJAX code ...
// Following example of code is for server side checking of results.
// If you want you could do this checking of results on the
// client side, but somebody could know all the correct
// results if you do it on the client side. Be careful!
var questions =
[
{
question: 'True or false: 3 + 3 = 6?',
answers: ['False','True'],
correctAnswer: 1
},
{
question: 'What sound does a dog make?',
answers: ['Meow','Mooo','Woof'],
correctAnswer: 2
},
{
question: 'Which from movie names below is a science fiction movie?',
answers: ['Star Wars','Planet of the Apes','Lion King','Shrek'],
correctAnswer: 1
},
];
var arAllAnswers = strAllAnswers.split(',');
var result = '<h3>Results</h3>';
for(var i = 0; i < questions.length; i++)
{
result += '<p><b>' + questions[i].question + '</b></p>';
result += 'Your answer was: ' + questions[i].answers[arAllAnswers[i]] + '<br>';
result += 'Correct answer is: ' + questions[i].answers[questions[i].correctAnswer];
}
var resultPage = document.querySelector('#result');
resultPage.innerHTML = result;
resultPage.style.display = 'block';
}
label{cursor:pointer}
<div class="quiz-page">
<p><b>Question 1 of 3.</b> True or false: 3 + 3 = 6?</p>
<label><input type="radio" name="question0" value="0">False</label><br>
<label><input type="radio" name="question0" value="1">True</label>
</div>
<div class="quiz-page" style="display:none">
<p><b>Question 2 of 3.</b> What sound does a dog make?</p>
<label><input type="radio" name="question1" value="0">Meow</label><br>
<label><input type="radio" name="question1" value="1">Mooo</label><br>
<label><input type="radio" name="question1" value="2">Woof</label>
</div>
<div class="quiz-page" style="display:none">
<p><b>Question 3 of 3.</b> Which from movie names below is a science fiction movie?</p>
<label><input type="radio" name="question2" value="0">Star Wars</label><br>
<label><input type="radio" name="question2" value="1">Planet of the Apes</label><br>
<label><input type="radio" name="question2" value="2">Lion King</label><br>
<label><input type="radio" name="question2" value="3">Shrek</label>
</div>
<div id="result" style="display:none"></div>
<br>
<input type="button" value="Next" onclick="goToNext(this)">
此代码应该适用于 iBooks、Android、Windows 平板电脑和台式机。
关于javascript - 跨电子书页面共享数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51999486/