JavaScript работает в версии 2.0 Anki, но не в версии 2.1

Я использую Анки, чтобы помочь сыну 5-го класса изучать математику. Мой сын достиг того момента, когда ему нужно проанализировать, как подходить к конкретным проблемам, а не просто запомнить факты.

Например, представьте, что вы пытаетесь научиться умножать дроби... .45 X .61 =?

Мне нужен был способ поместить случайные математические вопросы в карту Anki. Это означает, что однажды карта отобразит.45 X.61 =? В следующий раз, когда карта будет отображаться, вопрос может быть.. .34 X .12 =?

Поискав в интернете, я смог найти статью, которая объясняет, как это сделать...

https://yingtongli.me/blog/2015/03/15/random-question-generator-on-anki-using.html

Я не разработчик JavaScript, но я смог заставить эту технику работать после того, как в течение недели бился головой о клавиатуру.

Позвольте мне объяснить, как вы это делаете, а затем я объясню, где проблема.

Установите версию Анки 2.0.

Откройте Anki и создайте новую колоду.

Добавьте новую карту в колоду.

Откроется диалоговое окно добавления карты. В самом верху две длинные кнопки... "Тип" и "Палуба". Нажмите на кнопку "Тип" слева.

Откроется диалоговое окно "Выбор типа заметки".

Нажмите на кнопку "Управление" в нижней части диалогового окна.

Выберите основной тип заметки и нажмите кнопку "Добавить" слева.

Первый вариант должен быть "Добавить базовый". Нажмите кнопку "ОК" в нижней части диалогового окна.

Назовите новый тип заметки. "Тип заметки со сценарием", затем нажмите "ОК"

Хит бежать.

Теперь выберите новый тип заметки ("Тип заметки со сценарием") и нажмите "Выбрать".

Теперь мы хотим добавить дополнительное поле. По умолчанию этот тип заметки имеет поля с именами "Front" и "Back". Мы хотим добавить третье поле с именем "Скрипт".

Вверху слева есть кнопка с надписью "Поля". Нажмите на эту кнопку.

Появится другое диалоговое окно. Слева находится кнопка Добавить. Нажмите на это.

Введите Script в появившемся диалоговом окне и нажмите кнопку "ОК".

Теперь закройте текущее диалоговое окно, нажав кнопку закрытия рядом с кнопкой в ​​правой части.

Давайте настроим наши карты сейчас. В левом верхнем углу текущего экрана находятся две кнопки. Кнопка справа обозначена надписью "Карты". Нажмите эту кнопку.

Здесь мы настраиваем шаблон карты. Одна часть кода JavaScript входит в шаблон Front. Здесь должен быть следующий текст...

{{Фронт}}

Удалите все и вставьте следующий код.

<script>

function persist(cb) {
    window.setTimeout(function() {
        // Determine whether to use Anki's Bridge object (Desktop) or sessionStorage (AnkiDroid) to store data across sides.
        var dummy = {};

        var mode = "dummy";
        if (typeof(py) !== "undefined") {
            mode = "py";
            py.data = py.data || {};
        } else if (typeof(sessionStorage) !== "undefined") {
            mode = "sessionStorage";
        }

        var dataObj = {
            setItem: function(key, val) {
                if (mode === "dummy") {
                    dummy[key] = val;
                } else if (mode === "py") {
                    py.data[key] = val;
                } else if (mode === "sessionStorage") {
                    sessionStorage.setItem(key, val);
                }
            },
            getItem: function(key, def) {
                var val = undefined;
                if (mode === "dummy") {
                    val = dummy[key];
                } else if (mode === "py") {
                    val = py.data[key];
                } else if (mode === "sessionStorage") {
                    val = sessionStorage.getItem(key);
                }
                if (val == null) {
                    return def;
                } else {
                    return val;
                }
            },
            tryItem: function(key, val) {
                var currVal = dataObj.getItem(key, undefined);
                if (currVal == null) {
                    dataObj.setItem(key, val);
                    return val;
                } else {
                    return currVal;
                }
            },
            clear: function() {
                if (mode === "dummy") {
                    dummy = {};
                } else if (mode === "py") {
                    window.py.data = {};
                } else if (mode === "sessionStorage") {
                    sessionStorage.clear();
                }
            }
        };

        if (!document.getElementById("back")) {
            dataObj.clear();
        }

        cb(dataObj);
    }, 0); //Execute after Anki has loaded its Bridge object.
}

</script>

<script>

var code = (function () {/* {{Script}} */}).toString();
code = code.replace(/^[^\/]+\/\*!?/, "").replace(/\*\/[^\/]+$/, ""); //Strip beginning/ending comments.
code = code.replace(/<div>/g, "\n").replace(/<\/div>/g, "\n").replace(/<br \/>/g, "\n"); //Strip HTML.
code = code.replace(/&nbsp;/g, " ").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&amp;/g, "&"); //Replace special symbols.
eval(code);
</script>

<div id="front">{{Front}}</div>

Этот JavaScript берет код JavaScrippt, который мы поместим в поле "Сценарий", и выполняет его с помощью оператора eval.

Обратите внимание на то, что в этом коде функция постоянства поддерживает постоянные значения между лицевой и обратной сторонами карты Anki. Моя проблема связана с этой сохраняющейся функцией.

В нижней трети экрана находится "Задний шаблон". Удалите все и вставьте следующий код...

  {{FrontSide}}

<hr id=answer>

<div id="back">{{Back}}</div>

В правом нижнем углу нажмите кнопку "Закрыть".

Теперь нам нужно заполнить поля. Значения спереди и сзади не имеют значения. Я поставил "Фронт" спереди и "Назад" сзади.

Для поля "Сценарий" мы хотим добавить некоторый код. Нам нужно открыть представление HTML, прежде чем вставлять код. Убедитесь, что ваш курсор находится в полях Script.

В версии 2.0 Анки есть кнопка с изображением стрелки вниз в верхней правой части экрана. Версия 2.1 имеет "..." вместо кнопки со стрелкой вниз.

Нажмите на эту стрелку, и появится меню. Выберите пункт меню "Редактировать HTML".

Вставьте следующий код...

window.setTimeout(function(){

persist(function(data) {


var num1 = data.tryItem("num1",Math.random());


document.getElementById("front").innerHTML = num1; 
document.getElementById("back").innerHTML = num1;
});

},0);

Это работает в версии 2.0 Anki.

Вот вопрос

И вот ответ...

Мы сгенерировали случайное число в JavaScript, и это значение сохраняется между передней и задней частью карты Anki. Это открывает множество возможностей для карт математики и естественных наук Анки, использующих случайные числа.

Тем не менее, не все хорошо в Whoville.

Когда вы запускаете этот код на версии 2.1 Anki, он не работает.

Сценарий обходится, и отображаются статические значения полей Front и Back.

JavaScript все еще выполняется. Я мог бы поставить предупреждение в поле "Сценарий", и оно работает.

Проблема в персистентной функции. Новая версия Anki не нравится в функции Persist.

Может кто-то указать мне верное направление.

3 ответа

Решение

Проверить https://github.com/SimonLammer/anki-persistence Для достижения постоянства используются разные подходы.

Но среда Anki несколько непредсказуема, и вам нужно проверить, успешно ли инициализирован код.

Я понял...

Проблема в том, что Anki 2.1 исключил возможность хранить постоянные данные в объекте window.py.

Теперь вы можете спросить (как и я), что такое объект window.py? Я не уверен на 100%, но я считаю, что это внутренний объект Python, который допускает некоторые взаимодействия между JavaScript и Python. Анки написана на Python.

В любом случае window.py больше не доступен в Anki 2.1, что означает, что метод, который я описал в моем вопросе (см. Выше), больше не работает в Anki 2.1.

К счастью, автор статьи (ссылка на которую приведена выше в вопросе) упомянул, что объект window является общим для вызовов вопроса и ответа карты Anki.

Я начал играть с объектом окна в Javascript, и я смог получить постоянство данных, работая в Anki 2.1 (это также работает в Anki 2.0)

В приведенном выше вопросе я углубляюсь в эту технику, чтобы генерировать постоянные случайные значения в ваших картах Anki. Это означает, что вы генерируете случайное число в вопросе, и те же значения доступны в ответе. Я не буду вдаваться в подробности здесь, но обратитесь к вопросу выше для более подробной информации.

В "Front Template" есть код.

    <script>    
        var code = (function () {/* {{Script}} */}).toString();    
        code = code.replace(/^[^\/]+\/\*!?/, "").replace(/\*\/[^\/]+$/, ""); //Strip beginning/ending comments.

        code = code.replace(/<div>/g, "\n").replace(/<\/div>/g, "\n").replace(/<br \/>/g, "\n"); //Strip HTML.

        code = code.replace(/&nbsp;/g, " ").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&amp;/g, "&"); //Replace special symbols.

        eval(code);

    </script>    
<div id="front">{{Front}}</div>

Это тот же код из статьи. Я просто удалил код, который больше не работает.

Вот код скрипта карты...

window.setTimeout(function(){     

var windowsref = window; //Set a reference to the window object     

if ((("num1" in windowsref) == false) || windowsref.cnt != 1) {

            windowsref.num1 = Math.random();

            windowsref.cnt = 0;

   }      

windowsref.cnt++;

document.getElementById("front").innerHTML = windowsref.num1;

document.getElementById("back").innerHTML = windowsref.num1;     

},0);

Этот код работает только на рабочем столе Anki 2.1. Я также проверил iOS, и она работает там же.

Я надеюсь, что это помогает кому-то еще.

Рад слышать, что вы нашли решение, codingguy.

Для получения дополнительной информации, я хочу добавить, что в 2014 году у меня была та же идея. Я заставил ее работать, используя JavaScript и Cookies в своих шаблонах заметок.

Для этого мне пришлось модифицировать Anki с помощью плагина (для создания обезьяны-патча в Qt Web View), которым я поделился как плагин Anki 2.0 JS Booster. Адаптированный для Anki 2.1, другой разработчик опубликовал то же самое решение здесь, плагин Anki 2.1 Cookie Monster.

Другие вопросы по тегам