JavaScript работает в версии 2.0 Anki, но не в версии 2.1 - PullRequest
0 голосов
/ 29 января 2019

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

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

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

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

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

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

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

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

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

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

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

Удар по нажатию.

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

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

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

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

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

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

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

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

{{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, который мы поместим в поле «Script», и выполнит его с помощью оператора eval.

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

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

  {{FrontSide}}

<hr id=answer>

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

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

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

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

В версии 2.0 для Anki есть кнопка с изображением стрелки вниз в правой верхней части экрана.Версия 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.

Вот вопрос

The Question

А вот и ответ ...

The Answer

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

Однако в Уивилле все не так хорошо.

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

Anki 2.1 Error

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

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

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

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

Ответы [ 3 ]

0 голосов
/ 03 февраля 2019

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

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

0 голосов
/ 28 февраля 2019

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

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

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

0 голосов
/ 01 февраля 2019

Я понял это ...

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

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

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

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

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

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

В «Шаблоне фронта» приведен код.

    <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, и она работает там же.

Надеюсь, это поможет кому-то еще.

...