Делитесь данными на страницах электронной книги

Я хочу, чтобы в конце главы моей электронной книги epub3 с фиксированным макетом была викторина. Эта викторина займет несколько страниц и будет иметь несколько вариантов ответа. Каждый вопрос будет состоять из самого вопроса и четырех вариантов, каждый из которых имеет переключатель. В конце викторины пользователь нажимает кнопку, чтобы показать свой общий результат. Для этого мне нужно будет обмениваться информацией между страницами. Один из способов сделать это — разместить все страницы в одном XHTML-документе, а затем я могу сохранить ответы, которые студент дает на каждый вопрос, в переменной javascript. Однако допустимо ли иметь несколько страниц книги epub3 с фиксированным макетом в одном файле XHTML?, как я делаю здесь:

<?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.

Как бы вы посоветовали мне реализовать мою викторину?


person Baz    schedule 24.08.2018    source источник
comment
Я думаю, что window.sessonStorage ограничен только текущей вкладкой, а window.localStorage работает во всем браузере.   -  person Mean Coder    schedule 26.08.2018
comment
@Mean Coder Epubs не отображаются непосредственно в браузере.   -  person Baz    schedule 26.08.2018
comment
Возможно, вы захотите опубликовать суперкнигу вместо epub. Загляните на bookiza.io, если вы еще этого не сделали.   -  person Marvin Danig    schedule 27.08.2018
comment
@Baz, я не знаю, понимаешь ли ты, что я имею в виду в своем ответе, или нет. В связи с этим опишу его более подробно. Я предлагаю вам добавить ссылку на HTML-страницу с викториной (как в моем ответе) на каждую вашу страницу в документе ePub и над этой ссылкой вы могли бы порекомендовать принять участие в викторине. В этом случае вы добьетесь того, что ваша викторина будет поддерживаться во всех браузерах и операционных системах нативно. И в этом случае вам не пришлось бы программировать все это дополнительно. Если вас устраивает мой ответ, не могли бы вы отметить мой ответ как принятый слева от моего ответа, пожалуйста?   -  person Bharata    schedule 02.09.2018
comment
@Baz, и все эти HTML-страницы должны быть доступны онлайн на вашем сервере.   -  person Bharata    schedule 02.09.2018


Ответы (3)


Я думаю, что вы не очень понимаете, насколько сложно все это реализовать и поддерживать с помощью ePub. Я хотел бы порекомендовать вам прочитать о формате файла ePub. См. также последнюю версию спецификации формата ePub.

Публикация 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

Цитата из вашего вопроса: Я хочу, чтобы тест работал для iBooks, а также для планшетов и настольных компьютеров Android и Windows.

Браузеры изначально не поддерживают чтение и отображение файлов этого типа. Если вы действительно хотите иметь это, вам нужно все это запрограммировать. Вам это не особо нужно, потому что у нас уже есть библиотеки JavaScript:

  • Epub.js — библиотека JavaScript для рендеринга документов ePub в браузере;
  • Readium-js — механизм обработки EPUB, написанный на Javascript.

Но не забывайте: в обоих случаях обязательным условием является сервер NodeJS.

Тогда вам придется подумать обо всех ресурсах для этого процесса - это действительно слишком много! Слишком много работы по развитию, много ресурсов и слишком много энергии впустую!

Из-за всего этого никто не делает это таким образом.

Цитата из вашего вопроса: Как бы вы посоветовали мне реализовать мой тест?

Рекомендуемое решение от меня

У вас могут быть все вопросы для викторины в одном файле 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 и для настольных компьютеров.

person Bharata    schedule 27.08.2018

Согласно спецификации. , когда rendition:layout установлено на pre-paginated:

Данное исполнение предварительно разбито на страницы. Системы чтения ДОЛЖНЫ создавать ровно одну страницу для каждой ссылки на элемент корешка при рендеринге.

Насколько я понимаю, нет, недопустимо иметь несколько страниц в одном файле (если я правильно помню, это только файлы, на которые можно ссылаться в корешке/манифесте). Тем не менее, это может быть недействительным по существу для целей <nav>... Не стесняйтесь тестировать всесторонне, но ИМХО оно того не стоит, потому что...

...о хранении данных IDPF устанавливает много правил в отношении соблюдения читателей. Однако я серьезно сомневаюсь, что система чтения, которая отрицает использование сценариев, будет иметь большой успех, поскольку почти любое интерактивное поведение требует сценариев. Тем более, что этот формат в первую очередь предназначен для образовательных целей, где взаимодействие является отличным дополнением. Кроме того, сценарии могут быть отключены пользователем (согласно документу), конечно: в браузерах это тоже есть, кто его использует? Следовательно, localStorage. ;)

Наконец, как было сказано выше, это действительно не визуализация в браузере, но контекст очень близок к веб-браузеру с некоторыми ограничениями. Практически можно (должно?) предположить, что читатель является браузером, просто ограниченным вселенной, описанной его файлом пакета application/oebps-package+xml с причудливым типом MIME.

person Stock Overflaw    schedule 26.08.2018
comment
Сегодня я протестировал отправку данных с помощью sessionStorage между двумя страницами, но это не сработало - я тестировал в iBooks. Затем я попробовал точно такой же код, но с localStorage, и это сработало. Я бы подумал, что sessionStorage является подмножеством localStorage. Любая причина, по которой прежний не работает? - person Baz; 27.08.2018
comment
Никогда не использовал sessionStorage, но я бы сказал, что комментарий Mean Coder к вашему вопросу может ответить на это (то же самое сказано в MDN кстати). По какой-то конкретной причине вы хотели бы использовать session вместо local? - person Stock Overflaw; 28.08.2018

Я хотел бы, чтобы викторина работала для iBooks, а также для планшетов и настольных компьютеров Android и Windows.

Взгляните на Суперкниги, которые представляют собой веб-приложения/HTML-приложения, а не файловую систему книг, которая существует снаружи. сети. Я думаю, это поможет, потому что вы ищете что-то, что работает на всех устройствах и браузерах (планшетах, мобильных и настольных компьютерах), а также хотите добавить в книгу интерактивную викторину. Bookiza — это инструмент, который можно использовать для создания суперкниги.

Полное раскрытие: я создатель Bubblin и Bookiza.

person Marvin Danig    schedule 27.08.2018